Reputation: 573
I was writing a bit C99 code reading from stdin:
// [...]
fgets(buf, sizeof(buf), stdin);
// [...]
But I am wondering if I should catch errors in this case, since the shell could redirect stdin
to anything that may be less robust than plain stdin
. But that would also mean, that every access on stdin
, stdout
and stderr
has to be checked for errors, and I seldomly see any checks after printf
and co.
So, is it recommended to check every stream access for errors?
The above example would then be something like:
// [...]
if (!fgets(buf, sizeof(buf), stdin) && ferror(stdin)) {
exit(EXIT_FAILURE);
}
// [...]
Thanks in advance!
Upvotes: 0
Views: 2936
Reputation: 755026
You always have to check the return value from fgets()
, every time you use it. If you don't, you have no idea whether there is useful data in the buffer; it could hold the last line a second time. Similar comments apply to every read operation; you must check whether the read operation returned what you expected.
if (fgets(buf, sizeof(buf), stdin) == 0)
...EOF, or some error...
In the handling code, you need to decide what to do. You can legitimately use feof()
and ferror()
in that code. The correct reaction to the problem depends on your code. Detecting EOF is usually a cause for exiting the loop or exiting the function (break
or return
, but you only return if the function did not open the file; otherwise you have to close the file at least). Detecting errors on stdin
is going to be a rare occurrence; you will have to decide what's appropriate to do.
Detecting errors on write to stderr
or stdout
is something that's less often done, but it is arguably sloppy programming to omit them. One issue, especially if it is stderr
that has the problem, is "how are you going to report the error?" You might need to use syslog()
instead, but that's the sort of issue you have to think about.
Upvotes: 3
Reputation: 3484
Here's a fun exercise. Find someone's interactive program, run it until it asks for input from the terminal, and press control-D (EOF). Odds are that the author doesn't check feof(stdin) and his gets() calls keep just returning 0 bytes which the code interprets as a blank line. If it takes that as invalid input and re-prompts, it'll end up in an infinite loop!
Upvotes: 0
Reputation: 7610
It depends on the nature of the application you are developing. For example if you are developing a hard real time system whose abnormal termination results in severe problems. then you should take precaution to deal with all kinds of data streaming errors. On such situations use the following code,
if (!fgets(buf, sizeof(buf), stdin) && ferror(stdin)) {
exit(EXIT_FAILURE);
}
or some construct similar to it. But if your application's rare failures won't have any severe consequences you don't need to check every data streaming operation.
Upvotes: 1