I’d like to know the difference between stdout and STDOUT_FILENO in Linux/C, and after some research I came to the following understanding:
-
stdoutbelongs to the standard I/O stream of the C language, whose type isFILE*and is defined instdio.h. -
STDOUT_FILENOis anintvalue defined inunistd.h. It’s a file descriptor of LINUX system. Inunistd.h, it’s explained as follows:
The following symbolic constants shall be defined for file streams:
STDERR_FILENO File number of stderr; 2. STDIN_FILENO File number of stdin; 0. STDOUT_FILENO File number of stdout; 1.
So, in my opinion, the STDOUT_FILENO belongs to system-level calling and, to some extent, is like a system API. STDOUT_FILENO can be used to describe any device in the system.
The stdout is located at a higher level (user level?) and actually encapsulate the details of STDOUT_FILENO; stdout has an I/O buffer.
That’s my understanding about their differences. Could you help me review it and correct any mistake in it? Any comment or correction is appreciated, thanks.
stdoutis aFILE*pointer giving the standard output stream. So obviouslyfprintf(stdout, "x=%d\n", x);has the same behavior asprintf("x=%d\n", x);; you usestdoutfor<stdio.h>functions such asfprintf(),fputs()etc..STDOUT_FILENOis an integer file descriptor (actually, the integer 1). You might use it forwritesyscall.The relation between the two is
STDOUT_FILENO == fileno(stdout)(Except after you do weird things like
fclose(stdout);, or perhaps somefreopenafter somefclose(stdin), which you should almost never do! See this, as commented by J.F.Sebastian)You usually prefer the
FILE*things, because they are buffered (so usually perform well). Sometimes, you may want to callfflush()to flush buffers.You could use file descriptor numbers for syscalls such as
write()(which is used by thestdiolibrary), orpoll(). But using syscalls is clumsy. It may give you very good efficiency (but that is hard to code), but very often thestdiolibrary is good enough (and more portable).(Of course you should
#include <stdio.h>for the stdio functions, and#include <unistd.h>– and some other headers – for the syscalls likewrite. And the stdio functions are implemented with syscalls, sofprintf()may callwrite()).