2D Array of strings

Hi,
As a novice who has never worked with strings before, I'm looking for some help with string arrays please.
The concept is to setup a 2D array for displaying menu items on a 2x16 LCD. Thinking about this in terms of rows & columns, the logic was to create an array where each row would be a different menu item, 1st column would be a label (top row of LCD) & 2nd column a variable with units (bottom row of LCD), example: MAINS VOLTAGE (top row) 240VAC (bottom row).
As this is for an LCD all array entries are 16 characters.

First column of the array is straight forward as it's all labels (strings). I came across sprintf function which seemed logical for combining strings & variables and saving as a string into 2nd column of array.

I've constructed a simple test to trial this with unexpected results. The problem I'm having is every time I save something in the array using sprintf it overwrites all previous entries.

char* Array[][2] = {{"My test Array 00", " My test Array01"},
                    {" MAINS VOLTAGE  ", "                "},
                    {"My test Array 20", "                "},
                    {"My test Array 30", "                "},
                    {"My test Array 40", "Run away Quickly"}};

char  tmp[17];

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

void loop() {
  int c;
  int r;
  int v = 240;

  sprintf(tmp, "%s%d%s", "     ", v, " VAC    ");
  Array[1][1] = tmp;
  Serial.println(tmp);
  Serial.println(Array[1][1]);

  v = 150;

  sprintf(tmp, "%s%d%s", "     ", v, " Vdc    ");
  Array[2][1] = tmp;
  Serial.println(tmp);
  Serial.println(Array[2][1]);
  Serial.println(Array[1][1]);
  v = 350;

  sprintf(tmp, "%s%d%s", "     ", v, " Vac    ");
  Array[3][1] = tmp;
  Serial.println(tmp);
  Serial.println(Array[3][1]);
  Serial.println(Array[1][1]);
  for (c = 0; c < 5; c++)
  {
    Serial.println('\n');
    Serial.println(Array[c][0]);
    Serial.println(Array[c][1]);
    delay(1000);
  }
  while (1);
}

Result on the serial monitor is:

It appears that every time sprintf is run, it overwrites all previous occurrences.
I haven't been able to find any examples or tutorials that cover this so hoping someone can help please.

Array[1][1] is a pointer to tmp, so whenever tmp changes, the value pointed to by Array[1][1] changes.

Instead you can try:

char Array[][2][17] = {{"My test Array 00", " My test Array01"},
// ...

void loop() {
  // ...

  sprintf(tmp, "%s%d%s", "     ", v, " VAC    ");
  strcpy(Array[1][1], tmp);
  // ...
}

Or directly:

  sprintf(Array[1][1], "%s%d%s", "     ", v, " VAC    ");

Your array only holds pointers to statically allocated memory areas not fit for change. You need actual memory to be there for your sprintf work or use a temporary buffer for the display (and define the array as const char * because that’s what it is)

Edit: BTW in @jfjlaros approach you can directly snprintf() into the destination string without needing the tmp buffer on Top and the strcpy(). (Make sure to never overflow the reserved space - so snprintf() is preferred or strlcpy() / strncpy() when needed if you are not totally sure about the resulting string size)

Thanks for the quick replies.
Array[1][1] is a pointer to tmp ... amazing how you can look at something and not see the obvious.

Also note the comments about statically allocated memory. This gives me some direction.
I'll have a play & see how I go.
Thanks both for your time.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.