Other functions
sprintf
One commonly used function in the standard C library is sprintf()
, which is used to format a string with variables. This also includes variations like snprintf()
and also functions that call snprintf()
internally, like Log.info()
and String::format()
.
This example shows several common formatting techiques along with the expected output.
#include "Particle.h"
SerialLogHandler logHandler;
int counter = 0;
const std::chrono::milliseconds testPeriod = 30s;
unsigned long lastTest = 0;
void runTest();
void setup() {
}
void loop() {
if (millis() - lastTest >= testPeriod.count()) {
lastTest = millis();
runTest();
}
}
void runTest() {
Log.info("staring test millis=%lu", millis());
// 0000068727 [app] INFO: staring test millis=68727
// To print an int as decimal, use %d
Log.info("counter=%d", ++counter);
// 0000068728 [app] INFO: counter=1
// To print an int as hexadecimal, use %x
int value1 = 1234;
Log.info("value1=%d value1=%x (hex)", value1, value1);
// 0000068728 [app] INFO: value1=1234 value1=4d2 (hex)
// To print a string, use %s
const char *testStr1 = "testing 1, 2, 3";
Log.info("value1=%d testStr=%s", value1, testStr1);
// 0000068728 [app] INFO: value1=1234 testStr=testing 1, 2, 3
// To print a long integer, use %ld, %lx, etc.
long value2 = 123456789;
Log.info("value2=%ld value2=%lx (hex)", value2, value2);
// 0000068729 [app] INFO: value2=123456789 value2=75bcd15 (hex)
// To print to a fixed number of places with leading zeros:
Log.info("value2=%08lx (hex, 8 digits, with leading zeros)", value2);
// 0000068729 [app] INFO: value2=075bcd15 (hex, 8 digits, with leading zeros)
// To print an unsigned long integer (uint32_t), use %lu or %lx
uint32_t value3 = 0xaabbccdd;
Log.info("value3=%lu value3=%lx (hex)", value3, value3);
// 0000068730 [app] INFO: value3=2864434397 value3=aabbccdd (hex)
// To print a floating point number, use %f
float value4 = 1234.5;
Log.info("value4=%f", value4);
// 0000068730 [app] INFO: value4=1234.500000
// To print a double floating point, use %lf
double value5 = 1234.333;
Log.info("value5=%lf", value5);
// 0000068731 [app] INFO: value5=1234.333000
// To limit the number of decimal places:
Log.info("value5=%.2lf (to two decimal places)", value5);
// 0000068732 [app] INFO: value5=1234.33 (to two decimal places)
// To print to a character buffer
{
char buf[32];
snprintf(buf, sizeof(buf), "%.3lf", value5);
Log.info("buf=%s (3 decimal places)", buf);
// 0000068733 [app] INFO: buf=1234.333 (3 decimal places)
Particle.publish("testing", buf);
}
// To print JSON to a buffer
{
char buf[256];
snprintf(buf, sizeof(buf), "{\"value2\":%ld,\"value5\":%.2lf}", value2, value5);
Log.info(buf);
// 0000068734 [app] INFO: {"value2":123456789,"value5":1234.33}
Particle.publish("testing", buf);
}
// Using String::format
Particle.publish("testing", String::format("{\"value1\":%d,\"testStr1\":\"%s\"}", value1, testStr1).c_str());
}
One caveat is that sprintf-style formatting does not support 64-bit integers. It does not support %lld
, %llu
or Microsoft-style %I64d
or %I64u
.
As a workaround you can use the Print64
firmware library in the community libraries. The source and instructions can be found in GitHub.
Variation | Supported | Purpose |
---|---|---|
sprintf() |
✓ | Prints to a buffer, but snprintf is recommended to prevent overflowing the buffer. |
snprintf() |
✓ | Prints to a buffer, recommended method. |
vsprintf() |
✓ | Prints to a buffer, using va_list variable arguments. |
vsnprintf() |
✓ | Prints to a buffer, using va_list variable arguments and buffer size. |
printf() |
Prints to standard output, use Log.info() instead. |
|
vprintf() |
Prints to standard output, using va_list variable arguments. Not supported. | |
fprintf() |
Prints to a file system file. Not supported. | |
vfprintf() |
Prints to a file system file, using va_list variable arguments. Not supported. |