string concatenation does not work

Hi,

I just started playing around with Arduino and here is what I have, when trying to concatenate some strings...

#define ARD_LABEL  111  // unique id 





void setup() {


 unique_id = "Id_"+ARD_LABEL; 


 Serial.println("Unique Label is : " + unique_id);


 delay(500);


}

The serial.println prints garbage, not what I expect. In fact in print another log message (have of it) that I have later in my code.

Unique Label is : tering a new user...

when the tering a new user... is the "garbage"

What am I missing?

It looks like some of your code is missing.

ignch90:
What am I missing?

Some of your code is missing. This snippet won't compile.

I'll recommend that you show us a complete sketch that illustrates the problem. If you want people to look at the sketch and recommend solutions, you'd be well advised to post a short, minimal sketch that demonstrates the problem that you're trying to solve. If you post a long and complicated sketch, a lot of readers will decline to look at it, and will move on to the next post.

To illustrate the importance of posting a complete sketch, note that we can't tell what kind of object unique_id is. It could be a character pointer, or maybe a String. We need to see its declaration to know what it is.

This is the code snippet you need… Anything after that does not affect the program. Anyway, since you mentioned that here is the complete code, but I doubt it makes any difference.

#include <Bridge.h>
#include <Parse.h>

#define ARD_LABEL  111  // unique id for this board

String unique_id ;

void setup() {

  // Initialize digital pin 13 as an output.
pinMode(13, OUTPUT);
 
// Initialize Bridge
Bridge.begin();
 
// Initialize Serial
Serial.begin(9600);
 
while (!Serial); // wait for a serial connection
Serial.println("Parse Starter Project");

// String for unique_id

unique_id = "Id_"+ARD_LABEL;
Serial.println("Unique Label is : " + unique_id);
delay(500);

}

void loop() {
      Serial.println("Looping...");
      delay(2000);
}

I removed everything from my code, and since the Serial.println prints either garbage or nothing…

here is the complete code, but I doubt it makes any difference.

Well, your first piece of code had no declaration or type for unique_id , so yeah, it does make a difference.

unique_id = "Id_"+ARD_LABEL;

If you want to concatenate two Strings, then the two things you are trying to concatenate need to be both Strings, or have a default conversion to Strings. Do they ?

In the programming language Java, the plus sign may be used to concatenate two strings. However:

  1. Both sides of the plus sign had better be strings. ARD_LABEL is not a string.

  2. Most people program Arduinos in C or C++, not Java. C never uses a plus sign to concatenate two strings. C++ could use the plus sign to concatenate two strings, but you had better have the right library - and use it properly.

Most Arduino users tend to avoid the String class. True, it brings a lot of easy-to-use stuff to the table, but it eats resources like crazy. Most would use C strings and the family of string processing functions (e.g., strcat(), strcmp(), strtok(), etc.) that are available.

ignch90:
... I doubt it makes any difference.

Well, yeah, it does. Now we can see that unique_id is a String.

Here's a quote from the reference page for the String Addition Operator page, saying, essentially, "don't do that:"

int sensorValue = analogRead(A0); 

String stringOne = "Sensor value: ";
 String stringThree = stringOne + sensorValue;
 Serial.println(stringThree);



results in "Sensor Value: 402" or whatever the analogRead() result is, but



int sensorValue = analogRead(A0);
 String stringThree = "Sensor value: " + sensorValue;
 Serial.println(stringThree);



gives unpredictable results because stringThree never got an initial value before you started concatenating different data types.

That page will probably clarify the correct coding for you.

I suspect that this code -

 unique_id = "Id_"+ARD_LABEL;

sees "Id_" as a lower-case-"s" string, and adds 111 to its pointer's value and returns the result to unique_id, which is then interpreted as a capital-"S" String, showing everything from that location to the first null character that it encounters. But, I don't know - something else could be happening..

This stripped-down code, without the unnecessary #include directives, seems to work:

#define ARD_LABEL  111  // unique id for this board
String unique_id ;
String tempString;

void setup() {
  // Initialize Serial
  Serial.begin(9600);
  while (!Serial); // wait for a serial connection

  Serial.println("Parse Starter Project");

  // String for unique_id
  tempString = "Id_";
  unique_id = tempString + ARD_LABEL;
  Serial.println("Unique Label is: " + unique_id);
  Serial.println("Done.");
}

void loop() {}

The concatenation in the Serial.println(), concatenating a constant string and a String variable, may not be entirely kosher, based on what I see on the reference page. It seems to work in this case, but it's probably wisest to avoid that construction, and, when you're concatenating Strings, concatenate only Strings.

ignch90:
I just started playing around with Arduino and here is what I have, when trying to concatenate some strings...
...

What am I missing?

111 isn't a string, that is what you are missing. So you should say "I am trying to concatenate a string and a number".

Try:

#define ARD_LABEL  111  // unique id for this board
String unique_id ;
#define xstr(s) str(s)
#define str(s) #s
void setup() 
{
  Serial.begin(115200);
  while (!Serial); // wait for a serial connection
  Serial.println("Parse Starter Project");
  unique_id = "Id_" xstr (ARD_LABEL);
  Serial.println("Unique Label is : " + unique_id);
}

void loop() { }

That prints:

Parse Starter Project
Unique Label is : Id_111

Somewhat shorter and less confusing is:

#define ARD_LABEL  111  // unique id for this board
void setup() 
{
  Serial.begin(115200);
  while (!Serial); // wait for a serial connection
  Serial.println("Parse Starter Project");
  Serial.print("Unique Label is : ID_");
  Serial.println (ARD_LABEL);
}
void loop() { }

Or you could use snprintf:

#define ARD_LABEL  111  // unique id for this board
void setup() 
{
  Serial.begin(115200);
  while (!Serial); // wait for a serial connection
  Serial.println("Parse Starter Project");
  char buf [10];
  snprintf (buf, sizeof buf, "ID_%i", ARD_LABEL);
  Serial.print("Unique Label is : ");
  Serial.println (buf);
}
void loop() { }
unique_id = "Id_"+ARD_LABEL;

"Id_" is a pointer into memory, equal to the place where the compiler has placed that constant string.
You then add 111 to that memory location, resulting in a pointer to string that references some completely unrelated stuff.
You then use the overloaded '=' operator of the C++ string class to set unique_id to whatever was at that location.

Absolutely. You may as well have asked:

unique_id = "Id_"+111;

Why does that print garbage?

I think the OP wants sprintf.

http://www.cplusplus.com/reference/cstdio/sprintf/

Thank you all for the replies, I managed to sort it out.