Search code examples
esp32arduino-c++

Serial.printf() with String object of which length is 11 or more


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

Solution

  • 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.