0

This Code:

String S0 = "";
String S1 = "1";
String S2 = "12";
String S3 = "123";
String S4 = "1234";
String S5 = "12345";
String S6 = "123456";
String S7 = "1234567";
String S8 = "12345678";
String S9 = "123456789";
String S10 = "1234567890";
String S11 = "1234567890a";
String S12 = "1234567890ab";
String S13 = "1234567890abc";
String S14 = "1234567890abcd";
String S15 = "1234567890abcde";
String S16 = "1234567890abcdef";
String S17 = "1234567890abcdefg";
String S18 = "1234567890abcdefgh";
String S19 = "1234567890abcdefghi";
String S20 = "1234567890abcdefghij";
Serial.printf("(0):%s\n", S0);
Serial.printf("(1):%s\n", S1);
Serial.printf("(2):%s\n", S2);
Serial.printf("(3):%s\n", S3);
Serial.printf("(4):%s\n", S4);
Serial.printf("(5):%s\n", S5);
Serial.printf("(6):%s\n", S6);
Serial.printf("(7):%s\n", S7);
Serial.printf("(8):%s\n", S8);
Serial.printf("(9):%s\n", S9);
Serial.printf("(10):%s\n", S10);
Serial.printf("(11):%s\n", S11);
Serial.printf("(12):%s\n", S12);
Serial.printf("(13):%s\n", S13);
Serial.printf("(14):%s\n", S14);
Serial.printf("(15):%s\n", S15);
Serial.printf("(16):%s\n", S16);
Serial.printf("(17):%s\n", S17);
Serial.printf("(18):%s\n", S18);
Serial.printf("(19):%s\n", S19);
Serial.printf("(20):%s\n", S20);

Gives This Result:

(0):
(1):1
(2):12
(3):123
(4):1234
(5):12345
(6):123456
(7):1234567
(8):12345678
(9):123456789
(10):�H�?
(11):�^�?
(12):_�?
(13):�_�?
(14):`�?
(15):0`�?
(16):�`�?
(17):a�?
(18):@a�?
(19):pa�?
(20):�a�?

Any ideas?? PS: IT IS OBVIOUS that for whatever platform it is being used, it is working for short strings and not for longer strings! And it has been answered in the comments after you have closed it! So if you do not know the answer instead of closing, maybe it is better to leave it for others to answer it...

AKTanara
  • 163
  • 5
  • 1
    Please provide a complete compilable code as example. – chrisl Mar 15 '22 at 17:37
  • 2
    For what board are you compiling with what core? The standard core doesn't have a `printf()` function for Serial. The ESP32 core does. And the ESP8266 core doesn't take `String` as a parameter for it. Please provide way more information about your setup – chrisl Mar 15 '22 at 17:42
  • 3
    Well, I was working on making you an answer, but... then someone closed it. So, here: you need `.c_str()` in your calls. `.printf()` is a variadic function which doesn't really have access to any sort of destination type to do conversions; it relies entirely on your passing the correct format specifiers. It is just supplying the bytes to the `String` object, which is not simply a `const char *` (specified `%s`). If you're curious, the behaviour difference you're seeing is down to whether "small string optimization" is being used. – timemage Mar 15 '22 at 19:45
  • 1
    @timemage Appreciate the time and effort you put explaining this. I would definitely ACCEPT and UPVOTE your answer if someone hasn't decided to close it just because they simply do not know the answer!!! Just by adding .c_str() to S20 I got what I expected and your explanation was TRUE and invaluable. It also proved that no more explanation was required to clarify this obvious question. MANY REGARD – AKTanara Mar 15 '22 at 20:59
  • I guess the question was closed because of its quality. Though in the meantime it was reopened (possibly due to the answer in the comments), so @timemage can now put the comment as an answer. – chrisl Mar 16 '22 at 10:37
  • 1
    Looks like short string optimization, where shorter strings are stored directly in the object and for longer strings it's used as pointers. You should use: `Serial.printf("%s",Sxx.c_str());` – KIIV Mar 16 '22 at 13:23
  • 1
    @chrisl If I did that now it would be 95% diatribe fueled by contempt. – timemage Mar 16 '22 at 20:25
  • 1
    @AKTanara If you want you can find me and a small collection of others on libera.​chat irc network. – timemage Mar 16 '22 at 20:26
  • Dear timemage, I'll find you there as soon as I find out how this libera.​chat irc network works... Thanks again for the good answer you provided and I wished you could post your comment as answer now that the thread is open again so that I can accept it since you were the first one to mention the solution even when it was closed... – AKTanara Mar 18 '22 at 01:52
  • 1
    @AKTanara, I'm not worried about that. I've been helping people on IRC for a very long time and there's never been a point system there. RowanP has taken the time to turn it into an answer; it's probably better that you accept that answer so that the question is resolved in a technical sense. – timemage Mar 18 '22 at 02:51

1 Answers1

4

(Community Wiki answer assembled from the comments)

Noting that the standard Arduino core doesn't have a Serial.printf() function. The ESP32 core does.

You need .c_str() in your calls. .printf() is a variadic function which doesn't really have access to any sort of destination type to do conversions; it relies entirely on your passing the correct format specifiers. It is just supplying the bytes to the String object, which is not simply a const char * (specified %s). If you're curious, the behaviour difference you're seeing is down to whether "small string optimization" is being used.

Short string optimization is where shorter strings are stored directly in the object and for longer strings it's used as pointers.

The suggested solution is to use: Serial.printf("%s",Sxx.c_str());

RowanP
  • 819
  • 4
  • 21