Stuck figuring out how to pass an array of char to a library

KrisKasprzak

Well-known member
All,

I'm writing a small menu system library where I would like to pass in an array of chars and have that array be stored with a certain menu item--kinda hard to explain...

Can anyone take a look at my pseodo code below and see if you can figure out how to pass an array of chars and have that array save with a specific char in a .h, I'm really stuck


// i have this array definition in my my .ino
const char *CarText[] = {"Blue", "Red", "White"};



// calling function to my library
// trust me this all works umnil I added the char array
MenuOption6 = MyMenu.add(1.2, CarText);




/////////// INO code
// goal to call in my function

MyMenu.draw();

// and on screen would print
Blue
Red
White



/////////////////// .h code
// method inside my library

int add(float Increment, const char *MenuText[] = NULL) {
ID++;
inc[ID] = Increment;
// I know this is wrong, but tried everything but the working solution
// may need to use strcpy not not sure how to get the number of elements to loop through

menutext[ID] = MenuText;

return(ID);

}


void draw(int TheID) {
// set color, cursor and all that jaz
d->print(menutext[TheID][0]);
d->print(menutext[TheID][1]);
d->print(menutext[TheID][2]);
}


private:
float inc[MAX_OPTION];
char menutext[MAX_OPTION];
 
If I'm understanding this right I believe you want "char menutext[MAX_OPTION]" to be "char **menutext[MAX_OPTION]" an array of double pointers so that you can do "menutext[ID] = MenuText;"
 
Thanks for responding.

I'll try that, but i do have a mental block when it comes to pointers, now a double pointer is new to me :)


first i create a bunch of arrays


MenuText0 = {"red", "blue", "white"}
MenuText1 = {"cat", "dog", "bird", "fish"}
MenuText3 = {"up", "down"}



then I pass the array to the library function to insode the lib all this stuff is stored like this
mt[0][0] = "red"
mt[0][1] = "blue"
mt[2][2] = "white"
mt[1][0] = "cat"
mt[1][1] = "dog"
mt[1][2] = "bird"
mt[1][3] = "fish"
mt[2][0] = "up"
mt[2][1] = "down"
mt[2][0] = NULL
mt[2][1] = NULL


The in my lib i can pass in the ID (first array element), and print

Printid(int id)

// and if Id were say 1

this would print
cat
dog
bird
fish
 
I was in the same boat, but I had to force myself to learn pointers because I know it would help me in the long run, you really have to experiment with them to get a good understanding.

I'll try to break it down a little bit because the different types can be confusing.

This is a single pointer
Code:
const char *text = "myText";
This pointer is essentially pointing to this array
Code:
const char text[] = {'m','y','T','e','x','t','\0'};

This is a pointer array
Code:
const char *text[] = {
  "myText", "myText1"
};
This pointer is essentially pointing to this double array
Code:
const char text[][] = {
  {'m','y','T','e','x','t','\0'},
  {'m','y','T','e','x','t','1','\0'}
};

So if you want to pass around the double array, you need to store it to a double pointer like this
Code:
const char **textPtr = text;
Now you can use this double pointer as if it was the original pointer array such as this
Code:
Serial.print(textPtr[0]); //Prints "myText"
Serial.print(textPtr[1]); //Prints "myText1"
 
The following code works, there is an ugly cast from (const char **) to (char **) in the addMenu, since I had trouble defining a non const array of arrays of const character strings.

Code:
const char *CarText[] = {"Blue", "Red", "White"};
const char *FruitText[] = {"Apple", "Orange"};

char ** menutext[5];
int menuitems[5];

void setup() {
  // put your setup code here, to run once:
  Serial.begin(115200);
  delay(100);
  Serial.println("Hello menu");
  addMenu(0, CarText, 3);
  addMenu(1, FruitText, 2);
  printMenus();
}

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

}

void addMenu(int id, const char **MenuText, int items) {
  menutext[id] = (char **)MenuText;
  menuitems[id] = items;
}

void printMenus() {
  for (int ID=0; ID<2; ID++){
    Serial.println();
    Serial.print("== MENU "); Serial.println(ID);
    for (int item=0; item<menuitems[ID];item++) {
      Serial.println(menutext[ID][item]);  
    }
  }
  
}
 
@mlu, The next time I'm in Sweeden, I will buy you beer(s)!. My original menu code (5 screens with up to 10 items per screen with several listmenus) compiled at ate close to 30K memory. Your suggestions took it down to around 3K. Im sure i can optimize some more, but this is prefect.

Pointers are starting to sink in and this example sure helped.
 
Back
Top