Printf on Arduino

stdout is defined as a macro in stdio.h

/**
   Stream that will be used as an output stream by the simplified
   functions that don't take a \c stream argument.
   The first stream opened with write intent using \c fdevopen()
   will be assigned to both, \c stdin, and \c stderr.
*/
#define stdout (__iob[1])

I assume the comment is wrong (wrong copy paste from the above comment?) and they meant will be assigned to stdout

So as this is the first stream opened with write intent using fdevopen(), you get stdout automagically.

Source code shows that this is actually done

1 Like

6 posts were split to a new topic: Off Topic Because I Say So

snprintf() is the safe alternative to sprintf(). snprintf() guards against buffer overflow.
There is no similar 'n' safe alternative to dtostrf(). :frowning:
There is a safe two line alternative but the moderator @Coding_Badly (aka "Off Topic Because I Say So") won't let me post it here. :frowning: :frowning:

which includes adding a large library to your code behind it and embrace a new way of dealing with strings.

if you are on a 8 bit Arduino, there is no double precision, it's only float and so you know you don' have more than 7 decimal digits precision anyway which is enforced by the ftoa_engine, so you can easily get the right size for the char buffer (which you do in your library but you won't get the expected precision beyond 7 on a MKR or ESP with your library).

If you are on a 32 bit Arduino, you can use snprintf() but it comes at a memory footprint cost too (but likely there anyway because of the other libraries).

if you are a bit adventurous and want to go back in time, you can write your own function using ecvt() (legacy in POSIX 2001, removed in 2008 in favor of s(n)printf).

You can try this on an ESP32

#include <stdlib.h>

void printDoubleWithBufferRepresentation(double x) { // arbitrary 15 string size used, could be a parameter 
  int decpt, sign;
  char * conversionStr = ecvt(x, 15, &decpt, &sign); // legacy in POSIX 2001, removed in 2008 in favor of s(n)printf
  Serial.write(sign ? '-' : ' ');
  if (decpt <= 0) {
    Serial.print("0.");
    Serial.println(conversionStr);
  } else {
    Serial.write(conversionStr, decpt);
    Serial.write('.');
    Serial.println(conversionStr + decpt);
  }
}

void setup() {
  Serial.begin(115200);
  Serial.println();
  printDoubleWithBufferRepresentation(0);
  printDoubleWithBufferRepresentation(0.1234567890123456789);
  printDoubleWithBufferRepresentation(-0.1234567890123456789);
  printDoubleWithBufferRepresentation(42.1234567890123456789);
  printDoubleWithBufferRepresentation(-42.1234567890123456789);
}

void loop() {}