Behavior of fscanf when format doesn't match f

2019-08-06 03:57发布

问题:

If the contents of a file do not match the format string passed to fscanf, what happens on the next call to fscanf?

Suppose a file contains the following two lines:

9000 pig dog
4 5 2

A program tries to parse the opened file (fp) as such:

int a = 1, b = 1, c = 1;
int x = 1, y = 1, z = 1;

fscanf(fp, "%d %d %d", &a, &b, &c);
fscanf(fp, "%d %d %d", &x, &y, &z);

I suspect that a would now hold 9000 while b and c continue to hold the value 1 -- but what happens to x, y, and z?

Does the C99 standard guarantee that x, y, and z will hold the values 4, 5, and 2 respectively -- or is the file stream's position indicator guaranteed to be left unmodified after a failed parse, causing x to hold the value 9000 while y and z hold on to the value 1?

回答1:

Section 7.19.6.2

4) The fscanf function executes each directive of the format in turn. If a directive fails, as detailed below, the function returns. Failures are described as input failures (due to the occurrence of an encoding error or the unavailability of input characters), or matching failures (due to inappropriate input).

5) A directive composed of white-space character(s) is executed by reading input up to the first non-white-space character (which remains unread), or until no more characters can be read.

9) An input item is read from the stream, unless the specification includes an n specifier. An input item is defined as the longest sequence of input characters which does not exceed any specified field width and which is, or is a prefix of, a matching input sequence. The first character, if any, after the input item remains unread.

So a will be 9000 and b and c continue to be 1. The stream is read upto (but not including) pig, so the first %d of the second call immediately fails, causing x, y and z to remain 1.



回答2:

Summarizing from my handy copy of "Standard C" by Plauger and Brodie, fscanf() returns on...

  • end of format string
  • EOF on file
  • conversion failure

On conversation failure, it's not stated clearly, but I assume the failing character is pushed back on the stream. So your "p" character would be on the stream.

Note that the return value of fscanf() is the # of input items matched. So success for you would be a return of 3 each time. I'd expect returns of 1 and 0 in your example.