is String obejct a good way to build up string from multiple pieces?

Status
Not open for further replies.

bboyes

Well-known member
is String object a good way to build up string from multiple pieces?

Have not used the String object before with Teensy, need to make up a 32-char message from multiple data pieces and send it off to an external display. Serial append/concat seemed reasonable vs writing my own code to copy parts of other strings into a char array. Then I got bitten by this anomaly/bug https://www.arduino.cc/en/Tutorial/StringAdditionOperator wherein it is written: Caution: You should be careful about concatenating multiple variable types on the same line, as you may get unexpected results.

I got the code to work by putting every concat on a separate line:
Code:
				String_1 = bufferString1;
				String_1 += " ";
				String_1 += key1.value;
				String_1 += " = ";
				String_1 += key1.text_ptr;

				Serial1.print('d');
				Serial1.println(String_1);

At one point, with multiple appends on one line I had the remote display showing data which should have been completely out of scope, implying that I had an errant pointer (hopefully just reading, not writing to my String(34)). But this gave me pause and made me wonder if String is really "safe" to use or if it is like running with scissors (more so than C/C++ itself). I'm trying to not go down a rabbit hole here (too many of those already). Would I be "better" off with sprintf? Something else?
 
Last edited:
If I understand it correctly, the point to that comment is that you should initialize String_1 first, as you have done, before you do any concatenation. After that, you can put the rest in one statement if you wish because String_1 has an initial value. This should work:
Code:
// Set an initial value
				String_1 = bufferString1;
// Now the multiple concatenations should be OK
				String_1 += " " + key1.value + "=" + key1.text_ptr;

I'm old-school and would use sprintf (or snprintf) anyway. It gives you control over the length and formatting of individual elements of the string.

Pete
 
If I understand it correctly, the point to that comment is that you should initialize String_1 first, as you have done, before you do any concatenation. After that, you can put the rest in one statement if you wish because String_1 has an initial value. This should work:
Code:
// Set an initial value
String_1 = bufferString1;
// Now the multiple concatenations should be OK
String_1 += " " + key1.value + "=" + key1.text_ptr;
Nope, that's wrong. Initializing String_1 or not doesn't make a difference. All that matters are the argument types to operator+. If in your example "key1.value" is a String, things work no matter what, if not it won't work.
 
String concat works with casting

@tni is on the right track apparently. Casting the individual chunks of other types seems to get around this. So for example, this works but ONLY with the String casts in there:
Code:
msg_top_String1 = 'd' + (String) habitat_a_menu_ptr->lcd_text_ptr_a + " 1";
state_msg_Str1 = msg_top_String1 + String(millis());
Serial1.println(state_msg_Str1);

My coding partner tried sprintf a while back and said it added 10K to the binary size. Maybe we should look at that again. String seems to add about 2K. Anyone have any real test data on sizes of String vs sprintf? And how does sprintf play with Serial, Serial1, Serial2, etc? Researching and documenting all these options could be a full time job...
 
You would use printf with Serial. E.g.
Code:
  Serial1.printf("Note  On, ch=%d, note=%d, velocity=%d\n\r",channel,note,velocity);

Pete
 
printf adds 16 kbytes to sketch size!

@el_supremo, thanks that worked great.

Adding just this line:
Code:
Serial1.printf("dBufferS1 %s, value %d, text %s\n\r", bufferString1, key1.value, key1.text_ptr);
and no other changes increases sketch size from to 22,252 to 38,688 - over 16 kbytes!
On Teensy3.2 maybe we can afford that hit if we get enough utility out of printf.
 
Status
Not open for further replies.
Back
Top