What do you mean by an x,y problem?
In this case, X is “I want to use standard C++ file operators to print to Serial” and Y is “how can I override the library definition of putchar and getchar”.
(Hmm - maybe I was wrong about this being an XY problem. I suppose it depends on what X is.)
But basically - a microcontroller is not a unix machine, and some of the idioms of C are not all that applicable. stdout is “where you can put stuff so that the shell can pipe and redirect it”. In that sense, There simply is no stdout in the context of a microcontroller.
I have attached some of the text from stdio.h in the arduino library folder. The answer seems to be:
- create a Stream object
- use fdevopen to associate that object with your user-supplied code
- use fprintf (etc) to printf to the stream.
Outline of the chosen API
The standard streams \c stdin, \c stdout, and \c stderr are
provided, but contrary to the C standard, since avr-libc has no
knowledge about applicable devices, these streams are not already
pre-initialized at application startup. Also, since there is no
notion of “file” whatsoever to avr-libc, there is no function
\c fopen() that could be used to associate a stream to some device.
(See \ref stdio_note1 “note 1”.) Instead, the function \c fdevopen()
is provided to associate a stream to a device, where the device
needs to provide a function to send a character, to receive a
character, or both. There is no differentiation between “text” and
“binary” streams inside avr-libc. Character \c \n is sent
literally down to the device’s \c put() function. If the device
requires a carriage return (\c \r) character to be sent before
the linefeed, its \c put() routine must implement this (see
\ref stdio_note2 “note 2”).
As an alternative method to fdevopen(), the macro
fdev_setup_stream() might be used to setup a user-supplied FILE