Why is it not possible to print a String object to the console?

Arg!! Have spent many hours on seemingly simple problem of displaying to the console. Keep running into this same problem of not being able to print any kind of formatted output to the console when trying to print a String object.

This fails compiling with a “cannot pass objects of non-trivially-copyable type ‘class String’ through ‘…’ …/wiring/inc/sparc_wiring_print.h” error.

String _time;

void loop()
    _time = String::format(Time.format("%H:%M:%S%"));
    Serial.printlnf("%s", _time);

It’s possible to directly print the String object like this


But it seems there is no way to do something like this (does not work).

    _time = String::format(Time.format("%H:%M:%S%"));
    Serial.printlnf("%s var1: %d, var2: %d", _time, _var1, _var2);

Am I missing something obvious?


I prefer:

Serial.printlnf("%s var1: %d, var2: %d", _time.c_str(), _var1, _var2);

Others prefer:

Serial.printlnf("%s var1: %d, var2: %d", (const char *) _time, _var1, _var2);

The problem is because the parameter to printlnf is a variable argument, the compiler doesn’t know that you want a c-string as the output format of the String object.

1 Like

That is the secret I was looking for! Thanks.

Wish it was easier to figure out some of this stuff. Was looking at the https://docs.particle.io/reference/firmware/core/#string-class thinking there was some kind of method (i.e. toString()) that could be called off a C++ String object that would make it the correct type for the printlnf. Looks the c_str() option and the (const char *) options are doing something like that. Either way is converting to the correct type for the various overrides? .

Either the c_str() or (const char *) techinques work with anything that returns a String object directly, as well. For example:

Serial.printlnf("%s var1: %d, var2: %d", Time.format("%H:%M:%S").c_str(), _var1, _var2);
Serial.printlnf("IP address: %s", WiFi.localIP().toString().c_str());

Am going to be using this allot. Am pretty clueless to figure out what is going on with the code unless it’s loaded up with Serial.printlf. This would a topic for another thread but it sure would be nice to have a debugger.


another option is to directly print the String or to concat(?) it:

Serial.println("System-Time: " + Time.format(TIME_FORMAT_ISO8601_FULL));
Serial.println(String::format("Serial: %d, last Measure: %d", deviceSerial, lastMeasure));
Serial.printlnf("DeviceID: %s", System.deviceID().c_str());
Serial.print("Firmware Version: "); Serial.println(System.version());

That is a good option too. Was playing around with the Serial.print* commands but could not figure out how they can work together to produce a nicely formatted multi-variable one-line string. So thanks for finally making it make sense. It seems there are soooo many little tricks and quirks to learn when working with C++.