Trouble with Array of Characters

What I want to do should be simple. Perhaps I am a simpleton!

I’d like to create an array of 60 entries, each to contain (as characters) a 3 digit number + a 2 digit “addendum.”
(The numbers will actually be integers ranging from 100 to 300; the addendum one of three sets of two letters)

Since the rest of the program works OK, I have extracted only a sample in which I declare an array, fill it with some data, and read the data back. This should be basic - but I seem unable to do it!

I’ve used indirect addressing for the array since it was recommended and it compiles - but I don’t know why.

I have copied the code for my test - including comments indicating SOME of the things I’ve tried and which have failed.

Certainly I am missing something basic here.

// Test of writing/reading to elements of an array

// These are left in from the original. Probably not needed here.

#include <ESP8266WiFi.h>
#include "HTTPSRedirect.h"
#include "DebugMacros.h"

#include "Arduino.h"

void setup() {



    delay(100);
  Serial.begin(115200);
  Serial.println();

  Serial.println("Starting");
  delay(2000);
  
                    }  // end of setup

void loop() {

// To establish the 50 columns needed later for data in WU/ST/CD states:

 char *celldata[30][7];  // Create an array of 30 entries; each with 6 characters + terminating /0

// above ng as string!
// Should it be String or char
// Cannot be declared in "setup"

 char y;
 char z;
  
Serial.println("Loop Start");

    for ( int j = 0 ; j <=10; j++ ){     // For test we need only a few entries

// invalid conversion   *celldata[j] = 'y' ;
// Invalid conversion   *celldata[j] = ' j ' + " WU";
// Invalid conversion    y = 'j' + " WU"; Single, not double quotes for a string!!
// Invalid conversion   *celldata[j] = j;
// Invalid conversion   *celldata[j] =  ('ABU') ;

//    ng        *celldata[3] = y ;
// ng ng        *celldata[3] = ( y );
// ng ng        *celldata[3] =  { 'uno' };                 
// OK! as char  *celldata[3] =  { "uno" };
// ng ng        *celldata[3] = ( char , "y") ;
// ng ng        *celldata[3] = '4';
// ng ng        *celldata[3] = ( '4');
                *celldata[3] = ("4");  // This compiles
  Serial.print(j);
  Serial.print(" a "); // just for reference in reading the output
// invalid conversion   z = celldata[j];
// z cannot be used as a function z = celldata(j);
//  Serial.print(z);
  Serial.print(" - ");   // Just again for reference
  Serial.println("=end of for");
  delay(1000);

     }  // end of "for" loop

delay(2000);

  }  // end of loop

Where do all those pointers in celldata point?

I THOUGHT that the pointers in *celldata pointed to the elements of the array.
Thus I thought I realized (at the comment of TheMemberFormerlyKnownAsAWOL)
that I should have used the statement y = &celldata[ j ] to get the data contained in the element. (y = char; is above.)
(I had NOT done this before.)
Unfortunately, that will not compile. It yields the error: "Invalid conversion. . . "

I could now try lots of other things, but would appreciate some more help first!

You only need 2D array, not 3D

 char celldata[30][7];  // Create an array of 30 entries; each with 6 characters + terminating /0

Re: comment by arduino_new

If I declare only char celldata[30]; how do I tell the array the size of each element?
(They will all be the same length - 6 characters of data. Numbers and letters, so I assume that I have to convert them to "char")

Pardon me but, this is starting to sound like an x-y problem.

What is the goal? *Must * the numeric part be represented as characters?

mattbaum:
Re: comment by arduino_new

If I declare only char celldata[30]; how do I tell the array the size of each element?
(They will all be the same length - 6 characters of data. Numbers and letters, so I assume that I have to convert them to "char")

Can you declare it as:

 char celldata[30][7];

?

I can declare the array directly as: char celldata[30][7]: and it will compile.

However, I can't figure out how to put data into a cell.
I've tried celldata[j] = (xyzabc) or celldata(j) = [123456] or celldata[j] = '123456'; - and get various compile errors.
Is there some other format I'm missing?
Or am I on the wrong track altogether?
(Reading what presumably is in there works with: Serial.print(celldata[j]); ; this compiles OK )

strcpy() would be one way.

But, I don't understand why you're storing an integer value as a character string. Why not store it as an integer (only bytes)? And, since there are only 3 possible "addendum" (whatever that is), they could be represented by a single byte -- perhaps as an enum.

I'd probably define a struct with an int member and an addendum member. Then, all you'd need is a 1-D array of these structs.

mattbaum:
Is there some other format I’m missing?

It would be helpful to read about c strings. There are tons more pages on the web on this subject.

I'll try strcpy() which seems easy to do (and probably will work.)

Since my numbers will be greater than 255, I thought that char would be easier. (I could subtract 100 from an int form, and add it back later.
My program develops the three "digrams" of two letters each. This also could be modified for compactness.

Thanks for the suggestions. I'll try them tomorrow! (Also may look into struct. Help here would also be appreciated.)

Will also look into c strings, as suggested by dougp.

i think you want an array of a class?

class entry {
  public: 
  int number;
  char* head;
};

 int i;
entry thing[60];


void setup() {
thing[1].number = 123;
thing[1].head = "ab";

thing[2].number = 555;
thing[2].head = "cd";

Serial.begin(9600);
Serial.print(thing[1].head);
Serial.print(thing[1].number);
}

void loop() {
  // put your main code here, to run repeatedly:

}

taterking:
i think you want an array of a class?

class entry {

public:
int number;
char* head;
};

Technically that’s equivalent to a struct, and you’ve missed out the necessary strcpy

taterking:
i think you want an array of a class?

A struct and class are essentially equivalent except for the default access mode. While it’s certainly possible to declare a class with its own functions, I don’t think it’s necessary for this simple application.

I’d subtract 100 from the number to bring it into the allowable range of a uint8_t and define a enum for this mystery “addendum”. Just two bytes to hold one record.

enum Addendum : uint8_t {ABC, DEF, GHI};

struct CellData {
  uint8_t number;
  Addendum add;
};

CellData data[5];

void setup() {
  data[0].number = 123;
  data[0].add = ABC;

  data[1].number = 233;
  data[1].add = DEF;

}

void loop() {
}

The struct approach suggested by gfvalvo looks like a good one that I had not thought of.

However, when I try the suggested code in a new instance of the IDE, I get an error at enum - Expected ; or ( before ( token.

What am I missing?

The code I posted in Reply #14 compiles verbatim.

Thanks very much gfvalvo for the suggestion on using struct.

I am new to this concept, but I seem to be getting the hang of it now.
Using this approach reduces the storage requirement considerably, at the slight expense of re-formatting the data when it is needed.

If I have any further problems, I will post them as a new topic. Thanks again!