I had read that both perror()
and printf()
write to the terminal screen. But perror()
writes to stderr
while printf()
writes to stdout
. So, to print errors why is perror()
used when printf()
can do it.
-
2http://stackoverflow.com/questions/3385201/confused-about-stdin-stdout-and-stderr – ashiquzzaman33 Dec 05 '15 at 09:06
6 Answers
printf()
cannot write to stderr
. fprintf()
can. perror()
always does.
There is no requirement that writing to either stdout
or stderr
writes to a terminal screen - that is up to the implementation (since not all systems even have a terminal). There is also no requirement that writing to stdout
and stderr
results in writing to the same device (e.g. one can be redirected to a file, while the other is redirected to a pipe).
perror()
will be implemented with built-in knowledge of the meanings of error codes, represented by the static errno
, which is used by various functions in the standard library to report error conditions. The meanings of particular values are implementation defined (i.e. they vary between compilers and libraries).

- 35,646
- 4
- 32
- 74
Because there could be configurations where you want stderr
printed to the console but the other output not printed at all (for example, to remove verbosity). In other cases you may need to redirect stderr
to write to a file, this is useful when you are in production and that file can be used to understand what went wrong on a remote computer you can't debug yourself.
In general, you gain more control on how console outputs are treated depending on their type.
See this answer to understand how you can do stream redirection in code.
Or, see this link on how you can force stream redirection to file or ignore a stream on an already compiled program (while invoking it in bash)

- 1
- 1

- 743
- 2
- 12
- 33
In addition to other answers, you might use fprintf(3) on stderr
and errno(3) with strerror(3) like
fprintf(stderr, "something wrong: %s\n", strerror(errno));
On GNU libc systems (many Linux systems), you could use instead %m
conversion specifier instead:
fprintf(stderr, "something wrong: %m\n");
You conventionally should output error messages to stderr
(see stderr(3)); see also syslog(3) to use system logging.
Don't forget to end the format string with \n
since stderr
is often line buffered (but sometimes not) or else use fflush(3)
For example, you might want to show both the error, the filename and the current directory on fopen
failure:
char* filename = somefilepath();
assert (filename != NULL);
FILE* f = fopen(filename, "r");
if (!f) {
int e = errno; // keep errno, it could be later overwritten
if (filename[0] == '/') /// absolute path
fprintf(stderr, "failed to open %s : %s\n", filename, strerror(e));
else { // we also try to show the current directory since relative path
char dirbuf[128];
memset (dirbuf, 0, sizeof(dirbuf));
if (getcwd(dirbuf, sizeof(dirbuf)-1))
fprintf(stderr, "failed to open %s in %s : %s\n",
filename, dirbuf, sterror(e));
else // unlikely case when getcwd failed so errno overwritten
fprintf(stderr, "failed to open %s here : %s\n",
filename, sterror(e));
};
exit(EXIT_FAILURE); // in all cases when fopen failed
}
Remember that errno
could be overwritten by many failures (so we store it in e
, in the unlikely case that getcwd
fails and overwrite errno
).
If your program is a deamon (e.g. has called daemon(3)) you'll better use system log (i.e. call openlog(3) after calling daemon
) since daemon
can redirect stderr to /dev/null

- 223,805
- 18
- 296
- 547
There are three standard stream stdin
stdout
stderr
. You can refer to know what is important of different stream.
For error messages and diagnostics ,stderr is used , to print on stderr Perror is used. printf can not do that. Perror is also used to handle errors from system call
fd = open (pathname, flags, mode);
if (fd == -1) {
perror("open");
exit(EXIT_FAILURE);
}
You can refer more about this in book The linux programming interface
void perror(const char *s)
Perror prints message in following sequence :
argument of s
, a colon , a space , a short message concerning error whose error code currently in errno
and newline
In standard C if s
is null pointer than only message will be printed . other things will be ignored
To understand more you can also refer page 332 of The complete reference C

- 3,744
- 1
- 16
- 30
A big advantage of using perror():
It is sometimes very useful to redirect stdout into /dev/null to only have access to errors since the verbosity of stdout might hide the errors that we need to fix.

- 36
- 4
perror
The general purpose of the function is to halt the execution process due to an error. The error message produced by perror is platform-depend. You can also print your own error message also.
printf
The general purpose of the function is to print message user defined and continue the execution.

- 7,730
- 4
- 32
- 67
-
4"*The general purpose of the function is to halt the execution process due to an error.*". `perror()` does *not* halt the program at all. – alk Dec 05 '15 at 09:10
-
-
1@alk it is generally used to halt the process e.g. perror(errno);exit(1); – Vineet1982 Dec 05 '15 at 09:23
-
2Well, then perror isn't used to halt the process. In your example, it's used together with halting the process. Thoug, I'm not sure I'd say that it's generally used only in that case. So please, don't mix perror with halting processes. – Anders Dec 07 '15 at 07:34