makeString does not make Strings correctly

Damn. Ever time, I think, I made a progress in learning the Arduino C/C++, I get kicked into my oops

Ok, this is the way to learn a programming-language, but to be honest, learning other languages has been much easier for me... Or, honestly, am I that stupid..? Anyway :)

Do you know, why that does not work? It should print "1 or 5", NOT "5 or 5". Again, thanks in advance! :)

char makedString[20];
int userSelectionMode = 15;
char bigstring[40];

void setup() {

  // This does not output "1 or 5", but "5 or 5". WHY!?
  char* lcdOutput = join3Strings(makeString(1), " or ", makeString(5));

  Serial.begin(9600);
  Serial.print(lcdOutput);
}

// Subroutine: makeString
char* makeString(int zahl) {
  makedString[0] = 0;
  itoa(zahl,makedString,10);
  return makedString;
}

// Subroutine: join3Strings
char* join3Strings(char* string1, char* string2, char* string3) {
  bigstring[0] = 0;
  strcat(bigstring, string1);
  strcat (bigstring, string2);
  strcat (bigstring, string3);

  return bigstring;
}

void loop(){
}

learning other languages has been much easier for me...

I suspect these other languages had native support for manipulating text strings. The C functions (like strcat) are very crude in comparison.

Or, honestly, am I that stupid..?

Certainly not. Even very experienced C programmers occasionally screw up manipulating strings.


In C, you have to provide storage for each string. This...

char makedString[20];

...sets aside storage for a single string with a maximum length of 19 characters. If you need to simultaneously store a second string, you will need a second place to store it...

char makedStringTheSecond[20];

This line of code...

char* lcdOutput = join3Strings(makeString(1), " or ", makeString(5));

...can be broken down into these steps...

  • Call makeString passing 1 as the argument
  • makeString returns with a pointer to the makedString buffer; this pointer is saved for later when join3Strings is called
  • Call makeString passing 5 as the argument
  • Note: at this point makeString has replaced the contents of makedString
  • makeString returns with a pointer to the makedString buffer; this pointer is saved for later when join3Strings is called
  • Call join3Strings with the three parameters; this call is essentially join3Strings( makedString, " or ", makedString )

In other words, you will need a buffer for the first call to makeString and a second buffer for the second call to makeString.

Hopefully, this version will get you on the right path (it isn't well tested)...

// Subroutine: makeString
char* makeString(int zahl) 
{
  static char buffer[4][20];
  static byte index;

  index = (index + 1) and 3;
  /* This isn't necessary and should be removed...
  makedString[0] = 0; */
  itoa( zahl, buffer[index], 10 );
  return buffer[index];
}
  • Brian

....or the much simpler:sprintf(makedString, "%u or %u", 1, 5);