CSC 209 lab 10 solutions, week of 19 July 2022
Question 7:
Problem:
Read a number from the file "foo", or return −1 if the file doesn't exist or
doesn't begin with a number.
Code:
int foonumber()
{
int x;
FILE *fp = fopen("foo", "r");
if (fp == NULL)
perror("foo");
if (fscanf(fp, "%d", &x) == 0)
return(-1);
return(x);
}
Solution:
int foonumber()
{
int x;
FILE *fp = fopen("foo", "r");
if (fp == NULL)
return(-1);
if (fscanf(fp, "%d", &x) != 1)
x = -1;
fclose(fp);
return(x);
}
Problems fixed above:
- If fopen() returns NULL, do not proceed! The specification of this
function says that it should return −1 in this case.
- But also, the specification seems to make it clear that it's ok if the
file doesn't exist; thus we shouldn't be calling perror(). In general,
sufficiently low-level library routines should not be calling perror(), but
rather, leaving it to the caller to call perror(), where applicable, which it
probably isn't in this case.
Whether the library routine calls perror() or not is part of the
specification.
- The author of the original code was apparently not thinking of the
possibility of fscanf() returning EOF (−1). If fscanf() returns anything other
than 1 to indicate a successful match and the filling up of the 'x' variable,
"foonumber"'s return value should be −1.
- It is necessary to fclose() the FILE* because we don't know that we're
about to exit. Presumably we often aren't about to exit.
- Thus the return(−1) for a bad fscanf() also needs changing because we
need to fclose() first. We could add a duplicate fclose() in the 'if' body,
but I think what I did above is cleverer.
(On the other hand, sometimes excessive cleverness is bad. I'm not sure
whether the above constitutes excessive cleverness.)
"It's impossible to foresee the consequences of being clever."
-- Christopher Strachey
[press 'back' in your web browser to return to the problems]