Sprintf() issue

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
 */

Try...

  sprintf(buf,"%09lu",val);

Try "%09ul"

Did you try it?

No. Does it have to be "l" before "u"?

Yup... :slight_smile:

OK.
Thanks to all, adding 'l' (lower L) solved the problem.

sprintf(buf,"%09lu",val);
  Serial.println(buf);

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.

ul vs lu in sprintf always catches me :frowning:

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.

2 Likes

It's good to know the compiler is able to do those checks at all! (Meaning comparing the format string to the parameters and their types)

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)

1 Like

"%u\l"

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.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.