Passing Multidimensional Char Array

Hi!

I'm using String object to manipulate text, but I decided to go by char arrays.

But I'm having problem accessing the char arrays

The code below I'm using String object:

String myString[3][2] = {{"Abcdefgh"},{"RandomText"},
                        {"12345678"},{"Dont know"},
                        {"JustAtest"},{"OtherTest"}};


void setup() {
  Serial.begin(115200);
  printArray((String*)myString,2,3);
}

void loop() {
 // Nothing
}

void  printArray(String* Array, int Columns, int Rows){
  for(int j=0 ; j<Columns ; j++)
    for(int i=0 ; i<Rows ; i++)
      Serial.println(Array[j*Rows+i]);
}

I can pass and access the members, it works perfectly.

But I don't know how to pass char arrays to the function.

I declared it like this:

char myArray[][2][11] = {{"Abcdefgh"},{"RandomText"},
                        {"12345678"},{"Dont know"},
                        {"JustAtest"},{"OtherTest"}};

//First Dimension = Rows
//Second Dimension = Columns
//Third Dimension = Text Max Length

I've tried accessing it like String object array and other ways, but it doesn't work.

Seeing it, the most difference is that I have to specify the Text Max Length as fixed in char arrays.

I want to pass the columns, rows and text length in the function and not declare it fixed globally.

Some help please?

Thanks!

I would get rid of the two dimensional array of arrays and just use a scheme with two dimensions, that is an array of char arrays.

If you really want your strings to be in a 3x3 matrix like that, you can virtual row and column coordinates and then calculate an actual index between 0 and 9, something like n = 3*i + j should work.

Isn't there I way to use it like this?

char* Member;

Member = myArray[0][1];

This example works without passing it to a function.

So is there a method to get a pointer (for using in str functions, for example)?

This might help you out.

http://arduino.land/FAQ/content/6/32/en/passing-arrays-to-functions.html

pYro_65:
This might help you out.

http://arduino.land/FAQ/content/6/32/en/passing-arrays-to-functions.html

I'm getting Access Denied (I registered), do I need to do something else to view this content?

Edit: I just did it by changing the language to English.

giova014:
I'm getting Access Denied (I registered), do I need to do something else to view this content?

Edit: I just did it by changing the language to English.

Ahh, thank you.

I've been wondering why people have been getting access denied (past year). It must be because of the language settings.

If you need something on the article clarified, ask away :slight_smile:

I read the article and I come up with the following:

char myArray[3][2][11] = {{"Abcdefgh","RandomText"},
                        {"12345678","Dont know"},
                        {"JustAtest","OtherTest"}};

void printArray(char (*Array)[3][2][11], int Columns, int Rows){
  char* Member;
  
  for(int j = 0; j<Rows ; j++){
    for(int i = 0; i<Columns ; i++){
      Member = (*Array)[j][i];
      Serial.println(Member);
    }
  }
}

void setup() {
  Serial.begin(115200);
  printArray(&myArray,2,3);
}

void loop() {
  /* Nothing */
}

This in the only way I could do, but in my view it is unpratical because of the fixed parameter char (*Array)[3][2][11].

I don't know how to progress...

Just fixing, my char array declaration was:

char myArray[][2][11] = {{"Abcdefgh"},{"RandomText"},
                        {"12345678"},{"Dont know"},
                        {"JustAtest"},{"OtherTest"}};

and now I corrected it:

char myArray[3][2][11] = {{"Abcdefgh","RandomText"},
                        {"12345678","Dont know"},
                        {"JustAtest","OtherTest"}};

and somewhat progressed, but still I don't think is pratical:

char myArray[3][2][11] = {{"Abcdefgh","RandomText"},
                        {"12345678","Dont know"},
                        {"JustAtest","OtherTest"}};

void printArray(char (*Array)[2][11], int Columns, int Rows){
  char* Member;
  
  for(int j = 0; j<Rows ; j++){
    for(int i = 0; i<Columns ; i++){
      Member = (char*)Array[j][i];
      Serial.println(Member);
    }
  }
}

void setup() {
  Serial.begin(115200);
  printArray(myArray,2,3);
}

void loop() {
  /* Nothing */
}

Any suggestion?

I don't know exactly how you want to access the array. This accesses your array.

char myArray[3][2][11] = {{"Abcdefgh","RandomText"},
                        {"12345678","Dont know"},
                        {"JustAtest","OtherTest"}};


void setup() {
  Serial.begin(115200);                        
}

void loop() {
  for(int x=0;x<3;x++) {
    for(int y=0;y<2;y++) {
      testFunct(myArray[x][y]);
      delay(1000);
    }
  }
}

void testFunct(char tBuf[]) {
  Serial.println(tBuf);
}

This also works.

char myArray[3][2][11] = {{"Abcdefgh","RandomText"},
                        {"12345678","Dont know"},
                        {"JustAtest","OtherTest"}};


void setup() {
  Serial.begin(115200);                        
}

void loop() {
  for(int x=0;x<3;x++) {
    for(int y=0;y<2;y++) {
      testFunct(x,y);
      delay(1000);
    }
  }
}

void testFunct(int tX, int tY) {
  Serial.println(myArray[tX][tY]);
}

edit: Both test sketches also work with the String data type, even though I do not recommend using that data type.

SurferTim thanks for your reply!

In the examples the variable and function are in the same sketch, but I'm ultimately trying to figure out a way to pass the array in a function, because the function is in a library and I need to manage the array members in this library.

I need a way to get a pointer to the array soh I can use it in other functions that use char* as parameter.

What difference would it make if the myArray is in a library? Declare the myArray variable public in the library. The first example I posted does pass a char*.

// this passes a char* to the position in the array
      testFunct(myArray[x][y]);

// and you can change the testFunct function to this:
void testFunct(char *tBuf) {
  Serial.println(tBuf);
}

The major point Tim mentioned before is: "I don't know exactly how you want to access the array."

Tims method in #10 is not passing an array but one element of it (myArray[x][y]), is this all you want?

Or will you be:

Needing access to the whole array (myArray), or just a single dimension (myArray[x]).

The whole array

giova014:
The whole array

Why do you need to pass a pointer to the whole array? The whole array is in your library, right?

How do you expect the function requiring a char* to know which of the six character strings to use?

Despite that, this passes the start of the array to the testFunct function.

char myArray[3][2][11] = {{"Abcdefgh","RandomText"},
                        {"12345678","Dont know"},
                        {"JustAtest","OtherTest"}};


void setup() {
  Serial.begin(115200);                        
}

void loop() {
  // this calls testFunct with a char* to the start of the array (myArray[0][0])
  testFunct((char*)myArray);
  delay(1000);
}

void testFunct(char* tBuf) {
  Serial.println(tBuf);
}

Another way would be to put the array inside a class, and have a method that returns a pointer to the first element of the particular string identified by it's row and column.

And then you could pass a pointer or reference to the class instance.

The only reason I could think of, to possibly need to do this, would be for language localization.

Perhaps you should rethink the actual problem that you are trying to solve.

Thanks for all the replies!

I see that in the end I can consider that the Rows,Columns and Length are constants, but I'm trying to make it more flexible, through changing the parameters of the function, so I can use it with multiple arrays with different dimensions.

So, after reading the comments and trying I came up with this (considering that the function is a library):

char myArray[3][2][11] = {{"Abcdefgh","RandomText"},
                          {"12345678","Dont know"},
                          {"JustAtest","OtherTest"}};

void printArray(char* Array, int Rows, int Columns, int Length){
  char* Member;
  for(int j = 0; j<Columns ; j++){
    for(int i = 0; i<Rows ; i++){
      Member = &Array[(j*Rows+i)*Length];
      Serial.println(Member);
    }
  }
}

void setup() {
  Serial.begin(115200);
  printArray((char*)myArray,3,2,11);
}

void loop() {
  /* Nothing */
}

And I can use a macro like this to make it "look" better:

#define Member(j,i) (&Array[((j)*Rows+(i))*Length])

This is the best method that I could find.

Essentially, all array bounds are constant. So if you are passing a whole array, that is relatively easy using a template. The compiler automatically fills in the blanks when you pass an array in (Array type and dimensions).

This is the method explained in the second half of my article I linked above.

char myArray[3][2][11] = {{"Abcdefgh","RandomText"},
                          {"12345678","Dont know"},
                          {"JustAtest","OtherTest"}};

template< typename T, int X, int Y, int Z >
  void printArray( T (&Array)[X][Y][Z] ){
    for(int x = 0; x<X ; x++){
      for(int y = 0; y<Y ; y++){
        Serial.println( Array[x][y] );
      }
    }
}

void setup() {
  Serial.begin(115200);
  printArray(myArray);
}

void loop() {
  /* Nothing */
}

pYro_65:
Essentially, all array bounds are constant. So if you are passing a whole array, that is relatively easy using a template. The compiler automatically fills in the blanks when you pass an array in (Array type and dimensions).

This is the method explained in the second half of my article I linked above.

This is totally new to me, really there are templates in the link you sent, but I completely ignored them, thinking it was another language.

Now I'm really thankful for showing me new possibilities!

It works even better than the code I showed.