number of elements in a char array?

Okay so i am trying to make a menu on a 4x20 LCD screen. On the top of the screen i would like to be able to tell the user what level he is on. To do this i will need the number of elements of the char array, which would correspond to the line. I could of course add the number manually, but that would be annoying when adding sub menues etc.

so far i have tried these options i could find through a search and none of them seems to work.

strLength = strlen(GUI);                 // ERROR!
strLength = sizeof(GUI)/sizeof(int);          // strLength =1!
strLength = sizeof(GUI)/sizeof(GUI[0]);    // strLength =1!

Here are my whole code. As you can see i would like it to give me the answer of 5 elements!

/* Written by Kristoffer P. Sminge 2014*/

#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <string>
LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);  // Set the LCD I2C address



char* mainMenu[] = {
  "Main Menu", "Seperation", "Options", "Manual Move", "Statisticks"};


void setup()   /*----( SETUP: RUNS ONCE )----*/
{
  Serial.begin(9600);
  lcd.begin(20,4);

}
void loop()   /*----( LOOP: RUNS CONSTANTLY )----*/
{
  navLCD(mainMenu);
  delay(10000);
}

void navLCD(char* GUI[]){
   int cursor=1;
   int strLength;
   
   strLength = strlen(GUI);
   
   Serial.print(strLength);
   lcd.print("__________________/_");
   lcd.setCursor(3,0);
   lcd.print(GUI[0]);
   lcd.setCursor(17,0);
   lcd.print(cursor); 
   lcd.setCursor(19,0);
   lcd.print(strLength);
   
  for (int i = 1; i < 4; i++){
    lcd.setCursor(0,i);
    lcd.print(GUI[i]);
    delay(500);
  }
}

Anyone have an idea?

Hi you get 1 as length because GUI is a pointer in your code and not an array. Hope this cab help you.

Okay i think i get what you are saying. But how do i then find the number of elements in my function? At this point i am using the main menu, but later i would like the same routine to be able to write my sub-menue's, when calle from my main loop.

But how do i then find the number of elements in my function?

You don't, unless there is something in the array that defines the end of the array, as the NULL in a NULL-terminated array of chars does. You need to pass the size to the function.

Sorry for being a bit of a newb here, but how do i NULL terminate my array?

I guess that then i would make a for-loop increment by one, until i hit the NULL value?

as said i am trying to make a menu system, do you guess think that i am on the right track or is there an easier way?

but how do i NULL terminate my array?

Which array? The array of pointers? The one called maniMneu? Or the one called GUI (in the function)?

I guess that then i would make a for-loop increment by one, until i hit the NULL value?

Yes.

am on the right track or is there an easier way?

Pass the number of items in the menu into the function.

Thank you for you guys for quick replies and sorry for being such a noob :slight_smile:

I would rather avoid having to send the length of the array every time i call my function. It seems that i would have to do it a lot of times, but maybe i am not seeing the big picture?

Okay so i think i have null terminated my arrays:

char* mainMenu[] = {
  "Main Menu", "Seperation", "Options", "Manual Move", "Statisticks", '\0'};

In my GUI function i now run this loop

  for (int a = 1; a < 20; a++){
    if(GUI[a] != "\0"){
      ++strLength;
    }
    else
      break    
  }

It will not compile, and if it could i am not sure it will work.

Here are the whole code, in case the parts did not make sense!

/* Written by Kristoffer P. Sminge 2014*/

#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <string>
LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);  // Set the LCD I2C address



char* mainMenu[] = {
  "Main Menu", "Seperation", "Options", "Manual Move", "Statisticks", '\0'};


void setup()   /*----( SETUP: RUNS ONCE )----*/
{
  Serial.begin(9600);
  lcd.begin(20,4);

}
void loop()   /*----( LOOP: RUNS CONSTANTLY )----*/
{
  navLCD(mainMenu);
  delay(10000);
}

void navLCD(char* GUI[]){
  int cursor=1;
  int strLength;

  for (int a = 1; a < 20; a++){
    if(GUI[a] != "\0"){
      ++strLength;
    }
    else
      break    
  }

  Serial.print(strLength);

  lcd.print("__________________/_");
  lcd.setCursor(3,0);
  lcd.print(GUI[0]);
  lcd.setCursor(17,0);
  lcd.print(cursor); 
  lcd.setCursor(19,0);
  lcd.print(strLength);

  for (int i = 1; i < 4; i++){
    lcd.setCursor(0,i);
    lcd.print(GUI[i]);
    delay(500);
  }
}

It seems that i would have to do it a lot of times, but maybe i am not seeing the big picture?

But the size shouldn't change.

'\0' is a NULL character. That's different from a NULL pointer.

    if(GUI[a] != "\0"){

Should simply be

    if(GUI[a])
      break

That didn't even compile, did it?

If you want to know how long the string is, you need strlen( GUI[0] ), strlen( GUI[1] ) etc.

GUI itself is an array of 5 pointers to char, not any number of char.

No it did not... but now it does :slight_smile: Thank you so much for your help :smiley:

i have this code now:

  int strLength=0;

  for (int i = 1; i < 20; i++){
    if(GUI[i]){
      ++strLength;
    }
    else{
      break;    
    }
  }

First i did not set strLength = 0, an i got some strange high value results. Is that because C++ just puts in a random number?

You are right that the length does not change. But i like my code to be as modular as possible, and maybe one day i will need the possibility to add menus in program, thus it will be nice to not have to count the number of elements :slight_smile:

for (int i = 1; i < 20; i++)

Just use strlen - it won't make the mistake of ignoring the first character.

ohh... one follow up question:

In the code above i have just made my for-statement with 20 iterations. I guess that i might as well put this to an infinite high number, since i put in a break in the loop.

Is there a best practice to do this? Or should i avoid infinity?

Just use strlen - it won't make the mistake of ignoring the first character.

OP can't use strlen(), because GUI isn't a string. It's an array of pointers, the last one of which is NULL.

OP does need to change the initial value of the loop to 0.

In the code above i have just made my for-statement with 20 iterations. I guess that i might as well put this to an infinite high number, since i put in a break in the loop.

You should use a while loop instead. No need to define an upper limit.

AWOL:

for (int i = 1; i < 20; i++)

Just use strlen - it won't make the mistake of ignoring the first character.

I did try using strlen but because it is a function that points to my array, this does not work (if i understood the first answer correctly?).

I start the iteration at 1 because the first element defines my headline for my display, so i don't want this to count as an option. Else, it was well spottet :slight_smile:

PaulS:
You should use a while loop instead. No need to define an upper limit.

How would i use a while loop? How would i increment i-variable to get it to loop through all of my array?

How would i use a while loop? How would i increment i-variable to get it to loop through all of my array?

int i = 0;
while(GUI[i])
{
   i++;
}
// At this point, i is the number of items in the array.

Of course :roll_eyes:

Thank you so much PoulS