To add leading zeros to a decimal value, I try the following simple sprintf() function that for some reason does not return the expected value.
Can anyone help me solve this one (or suggest another solution)?
char buf[40];
unsigned long val = 654321;
void setup()
{
Serial.begin(115200);
}
void loop()
{
sprintf(buf,"%09u",val);
Serial.println(buf);
delay(3000);
}
/* result:
Expected: 000654321
Received:
Serial port COM5 opened
000064497
Serial port COM5 closed
*/
Fair enough. Seems inconsistent, though. When specifying an unsigned long literal value, the compiler accepts "ul" or "lu". I'm surprised printf() format won't accept either.
Do you have your compiler warning level (in Preferences) set to anything below "All"? That might be keeping you from getting helpful warnings like this one:
In function 'void loop()':
sketch_oct19a.ino:11:27: warning: format '%u' expects argument of type 'unsigned int', but argument 3 has type 'long unsigned int' [-Wformat=]
sprintf(buf, "%09u", val);
^
I recommend you ALWAYS set the compiler warning level to "All" and fix as many of the warnings as you can.
But how would a user print an unsigned value followed by a literal l character if printf() took either %ul or %lu to print an unsigned long value? Just remember that printf() takes a more rigid "language" than C/C++ itself; the fields in a format specifier are always in the same order (%[flags][width][.precision][length]specifier)
Sure, I guess, but you'd have to escape the backslash in code (otherwise the compiler will treat \l as an invalid escape sequence):
printf("%u\\l", 42);
But keep in mind that printf is effectively a run-time command interpreter, and any additional features like this can only slow it down and add bloat the executable size for (IMO) little gain.