Printf, sprintf unsigned long

I have following test code:

vector<float> sensorData = sensor.getSensorData();// contains 3 floats
    Serial.println(sensorData[TEMP]);//0
    Serial.println(sensorData[PRESS]);//1
    Serial.println(sensorData[HUM]);//2
    Serial.printf( "Test: Time: %6ld, Temp: %.2f, Press: %.2f, Hum: %.2f\n",(unsigned long)i,sensorData[TEMP],sensorData[PRESS],sensorData[HUM]);
    Serial.printf( "Test: Time: %6l, Temp: %.2f, Press: %.2f, Hum: %.2f\n",(unsigned long)i,sensorData[TEMP],sensorData[PRESS],sensorData[HUM]);
   

this produces following output

26.00
959.00
76.00
Test: Time: 26, Temp: 26.00, Press: 959.00, Hum: 76.00
Test: Time: , Temp: 0.00, Press: 26.00, Hum: 959.00

as the formatting string %l was not correct for unsigned long, I would expect other results than seeing the output fields being printed in the wrong place!?

May I consider this to be a bug?
Arduino 2.3.2 for ESP32-S3

No.

A single 'l' is not a valid format specifier.

https://cplusplus.com/reference/cstdio/printf/

a7

l is a modifer; %l means nothing, so you got nothing.

As shown with the previous statement, the long unsigned i is 26, or 0x1A. The long is the same size as a float, 32 bits. So it is gets printed as %.2f. What is 0x1A interpreted as a float? A really small number, when rounded to two decimal places, is just 0.00.

void setup() {
  Serial.begin(115200);
  float sensorData[3] = {26.0, 959.0, 777.0}; // contains 3 floats
  unsigned long i = 12345678UL;
  unsigned long u = 12345678;
  Serial.println(sensorData[0]);//0
  Serial.println(sensorData[1]);//1
  Serial.println(sensorData[2]);//2
  Serial.printf( "Test: Time: %lu, Temp: %.2f, Press: %.2f, Hum: %.2f\n", i, sensorData[0], sensorData[1], sensorData[2]);
  Serial.printf( "Test: Time: %lu, Temp: %.2f, Press: %.2f, Hum: %.2f\n", u, sensorData[0], sensorData[1], sensorData[2]);
}

void loop() {
}

1 Like

This does indeed explain the behavior I noticed. But it took me a while to figure out where what was wrong :frowning: