My code.
void loop() {
if(Serial.available()) {
String str = Serial.readStringUntil('\n');
Serial.printf("String1:%s\n", str);
Serial.print("String2:");Serial.println(str);
Serial.printf("char*:%s\n", str.c_str());
}
}
Send 1234567890
with Serial. (length 10)
String1:1234567890
String2:1234567890
char*:1234567890
Send 12345678901
with Serial. (length 11)
String1:@��?
String2:12345678901
char*:12345678901
When I send String object from arduino(esp32) to computer with Serial.printf("%s"), if its length is 11 or more, the strange is sent.
String str = "12345678901";
Serial.print(str); // ok
Serial.println(str); // ok
Serial.printf(str); // incorrect syntax
Serial.printf("%s", str); // error
It has nothing to do with the length.
It's because you're passing a String
object to the %s
format in Serial.printf()
.
A String
is not a C string. The %s
format in printf()
is intended to work with a C string - it takes the value corresponding to it and treats it as a char *
- a pointer to a null-terminated array of characters, which is how the language C represents strings.
%s
does not work with String
objects. Hence the line:
Serial.printf("char*:%s\n", str.c_str());
does work because you called the c_str()
method on the String
object to get a pointer to its underlying C string.
When you write:
Serial.printf("String1:%s\n", str);
your program will print the binary contents of the str
object as if it were a C string, which it is not. You're lucky it didn't crash.
When you built the program, the compiler should have given a warning about the arguments passed to printf()
. Reading the warnings and errors that the compiler outputs can save you some grief.