So i wrote a basic printf and i was wondering if I even needed to re-create the wheel, I have seen a few posts in the past but I found nothing of use, and what's more could my implementation be simplified further, i know i have excluded half the types such as %x and such but its a start and better than writing Serial.print 5 times for one sentence.
printf_s("Some int %d, and a float %f, and a unsigned long %l, and a char string '%s'\n", 9, 8.56, 1000UL, "some Test String");
// Don't use printf as the name it will not be called correctly
void printf_s(const char* format, ...) {
int pos = 0; char c = format[pos++];
va_list arguments;
va_start (arguments, NULL);
c = format[pos = 0];
while (c != '\0') {
if (c == '%') {
const char type = format[++pos];
if (type == 's')
Serial.print((char*)va_arg(arguments, char*));
else if (type == 'd')
Serial.print((int)va_arg(arguments, int));
else if (type == 'l')
Serial.print((unsigned long)va_arg(arguments, unsigned long));
else if (type == 'f')
Serial.print((double)va_arg(arguments, double));
}
else
Serial.print(c);
c = format[++pos];
}
va_end (arguments);
}
I think that printf() uses a putchar() or so. If that is redirected to the Serial port, then it works. There are libraries for that.
The ESP32 has a Serial.printf(), inclusive 'float' and 'double'.
The Raspberry Pi Pico on the other hand does not have a Serial.printf().
The basic Arduino boards have a sprintf(), so then it is this:
IMO, the value of xxprintf() is the width formatting and padding and left/right adjustment.
If you look at all the 3rd party non Arduino.cc products, they all include a printf() method in their Print class.
This allows doing.
Serial.printf("this is an integer counter: %04d", counter);
So if using say ESP32, ESP8266, chipkit, Teensy, Intel, rp2040, STM32,.... etc. platform/cores you have a printf() method.
Arduino.cc absolutely refuses to add a printf() method to the Print class any of their platform/cores.
A while back a guy did an interesting formatting library called PrintEx.
It has not been maintained but perhaps worth a look if you are wanting to implement a fully featured formatting library that has a bit less overhead than a full xxprintf() implementation.
Here is a simple way to add a printf() like function for the Arduino environment.
I call the function Pprintf() (for "Print Class printf") and it works just like fprintf() but you pass in the Print class instead of a file pointer.
This allows you to direct the output to the device of your choosing.
i.e.
This PR may be relevant to this conversation. It implements the stream insertion operator to provide an easier interface to the Stream.print function. For example,
int a {9};
int b {10};
Serial << "You have " << a << " out of " << b << " retries left.\r\n";
// Prints: "You have 9 out of 10 retries left."
Serial << format(1.2, 4) << ' ' << format(12, BIN) << "\r\n";
// Prints: "1.2000 1100"