Support for leading zeros in Serial.print, etc.

One thing I see a lot of is people trying to display numbers with leading zeros. They end up writing code like this:

Serial.print(hh, DEC); // show hours
Serial.print(":"); // colon
if (mm<10) Serial.print("0"); // leading zero for minutes
Serial.print(mm, DEC); // show minutes
Serial.print(":"); // colon
if (ss<10) Serial.print("0"); // leading zero for seconds
Serial.print(ss, DEC); // show seconds

I request that you extend print to make this work:

Serial.print(hh, DEC); // show hours
Serial.print(":"); // colon
Serial.print(mm, DEC, 2); // show minutes (two figures)
Serial.print(":"); // colon
Serial.print(ss, DEC, 2); // show seconds (two figures)

This wouldn't break anything, would it?

It wouldn't break anything, but could possibly add unnecessary overhead to other users projects that do not use this functionality (depending how it was implemented).

I'm building my PrintEx library to address all these case specific issues. Using my custom printf() you can achieve this easily.

#include <PrintEx.h>

PrintEx print = Serial;

void setup() {
  Serial.begin(9600);

  char hh = 1;
  char mm = 5;
  char ss = 9;

  print.printf( "%02d:%02d:%02d", hh, mm, ss );
}

void loop() {}

This outputs:

01:05:09

You can install the library through the library manager (IDE 1.6.2 and above).

There is a basic rundown of features available here: GitHub - Chris--A/PrintEx: An extension to the Arduino Print library, and much, much more...

I'm also working on adding a specialized padding functionality for extended print methods which will alleviate the need to include the printf function (however it is smaller than the stdlib version which doesn't support floats).

1 Like

pYro_65:
It wouldn't break anything, but could possibly add unnecessary overhead to other users projects that do not use this functionality (depending how it was implemented).

It could also greatly reduce overhead from some projects. In particular, it would help in situations such as this one: Convert float to int without float initialization (mantissa) - Programming Questions - Arduino Forum

odometer:
It could also greatly reduce overhead from some projects. In particular, it would help in situations such as this one: Convert float to int without float initialization (mantissa) - Programming Questions - Arduino Forum

The print code would already be in use, extra print calls produces minimal overhead on top of what the first call would use. The logic in use for the leading zeros would simply be moved to the function call. It would only really be a convenience, and probably wouldn't save much, if anything (if only used a couple of times, but nothing a sketch based function couldn't otherwise provide). Whereas if you do not require that logic, its instant overhead.

pYro_65:
The print code would already be in use, extra print calls produces minimal overhead on top of what the first call would use.

Zero-padding would also provide next to no overhead.
All that the print function would have to do is stay in its loop a bit longer.

From the Arduino core:

size_t Print::printNumber(unsigned long n, uint8_t base) {
  char buf[8 * sizeof(long) + 1]; // Assumes 8-bit chars plus zero byte.
  char *str = &buf[sizeof(buf) - 1];

  *str = '\0';

  // prevent crash if called with base == 1
  if (base < 2) base = 10;

  do {
    unsigned long m = n;
    n /= base;
    char c = m - base * n;
    *--str = c < 10 ? c + '0' : c + 'A' - 10;
  } while(n);

  return write(str);
}

My fix (untested code):

size_t Print::printNumber(unsigned long n, uint8_t base, int8_t figs=1) {
  char buf[8 * sizeof(long) + 1]; // Assumes 8-bit chars plus zero byte.
  char *str = &buf[sizeof(buf) - 1];

  *str = '\0';

  // prevent crash if called with base == 1
  if (base < 2) base = 10;
  
  // prevent buffer overrun
  if (figs > (sizeof(buf) - 1)) figs = sizeof(buf) - 1;
  // print at least one digit
  if (figs < 1) figs = 1;

  do {
    unsigned long m = n;
    n /= base;
    char c = m - base * n;
    *--str = c < 10 ? c + '0' : c + 'A' - 10;
  } while((n>0)&&((--figs)>0));

  return write(str);
}

By the way, what happens when you print the number 190 in any base greater than 190?

Here's another project that practically cries out for this to be added:
http://forum.arduino.cc/index.php?topic=350918.0