I'm trying to make a menu and submenu system and running into all kinds of issues. Among them, when I try to declare the following arrays, I get the following error.
conversion from 'const String [2]' to non-scalar type 'String' requested
Reading through various sites, I believe this is happening because it has to convert things twice and can't do that. Some people propose using pointers, but:
- I'm very new to programming, and I don't really understand how. I'm hoping there is a simpler solution so I don't have to learn
- When I try to use pointers, certain functions such as sizeof(multidimensionalarray[0]) don't work properly, although I could be using them wrong
const String mainMenuItems[] = {"Item1", "Item2"}; //Menu level 0
const String modeMenuItems[] = {"Item3", "Item4", "Item5"}; //menu level 1
const String settingsMenuItems[] = {"Item6", "Item7", "Item 8", "Item 9"} //menu level 2
const String allMenus[][3] = {mainMenuItems, modeMenuItems, settingsMenuItems};
Are you aware of the pitfalls of using the String class?
There are strings (null terminated character arrays) and String objects. They are not the same.
conversion from 'const String [2]' to non-scalar type 'String' requested
The sizeof() function works on strings, not Strings. You must use functions that are made for the data type. The String class uses length() instead of sizeof().
groundFungus:
Are you aware of the pitfalls of using the String class?
There are strings (null terminated character arrays) and String objects. They are not the same.
The sizeof() function works on strings, not Strings. You must use functions that are made for the data type. The String class uses length() instead of sizeof().
Thank you for that information. I actually read through the whole thing and found it quite useful. Coming from Python and Perl, working with arrays and Strings in C++ is a pain.
That being said, I think many of the issues highlighted in the write up you linked probably don't apply to this scenario. Mainly because all the String arrays are declared as constant, so I don't believe they would be allocated to the heap. The only time the actual String is used is when they are part of a lcd.print function. Otherwise they are not manipulated and thus shouldn't contribute to heap fragmentation.
So is there a way to declare an array of string arrays?
omega_destroyer:
That being said, I think many of the issues highlighted in the write up you linked probably don't apply to this scenario. Mainly because all the String arrays are declared as constant, so I don't believe they would be allocated to the heap.
Nope, bad guess.
Declaring them as const doesn't not change the way they work with dynamic memory:
void setup() {
const String s1 = "Hello World";
//String s1 = "Hello World";
Serial.begin(115200);
delay(1000);
Serial.println(s1);
s1 += ", Goodbye World";
Serial.println(s1);
}
void loop() {
}
Compiles (with warnings) for an Uno.
Serial Port Output:
Hello World
Hello World, Goodbye World
So is there a way to declare an array of string arrays?
const char* array[][3] = {{"abc4", "def456", "ghi"},{"jklty", "mno521", "pqr"},{"stu", "6vwxoo", "yx1"}};
void setup()
{
Serial.begin(115200);
Serial.print("array = ");
Serial.println(array[1][1]); // prints "array = mno521"
}
void loop()
{
}
groundFungus:
const char* array[][3] = {{"abc4", "def456", "ghi"},{"jklty", "mno521", "pqr"},{"stu", "6vwxoo", "yx1"}};
void setup()
{
Serial.begin(115200);
Serial.print("array = ");
Serial.println(array[1][1]); // prints "array = mno521"
}
void loop()
{
}
Thanks this worked and I only had to slightly change the rest of the code to accommodate char vs String. 
However, I have to say that this whole experience with C++ has left me pretty jaded. For the casual (newbie) programmer like myself, having to deal with pointers and odd things like this to troubleshoot something that would be so simple in other languages makes it quite frustrating.
Thank you again, your solution worked and I ended up getting the code to work, but I still don't understand why I can't declare the three arrays within the array separately and feed them into the array as variables. e.g.
char array1[] = {....};
char array2[] = {....};
char array3[] = {...};
char arrayAll[] = {array1, array2, array3};
or char arrayAll[][] = {array1, array2, array3};
troubleshoot something that would be so simple in other languages makes it quite frustrating.
And now transport your "other languages" to architectures that have memory measured in kilobits.
How do they fare?
Because array names are treated as pointers. So, you'd have to have:
char *arrayAll[] = {array1, array2, array3};
That makes arrayAll an array of pointers to char.