Is getc () defined after EOF returns?

I use getc(); in Exercise C, and looking back at the program, I noticed something strange. I assumed that the file specified in the command line arguments contains at least one byte. (He calls getc(); twice in a row, without checking for EOF . After trying it on an empty file, it worked smoothly anyway. My question is: is the behavior of getc(); on a disabled file pointer (EOF reached and not rewound) undefined or will he always keep returning EOF?

I think I could expand this question to all the I / O functions in the C STL, clarify this in my answer too.

Here is the program code. It is assumed that the program should remove the source C / C ++ file from all comments (and it works fine).

 #include <stdio.h> int main(int argc, char *argv[]) { int state = 0; // state: 0 = normal, 1 = in string, 2 = in comment, 3 = in block comment int ignchar = 0; // number of characters to ignore int cur, next; // current character and next one FILE *fp; // input file if (argc == 1) { fprintf(stderr, "Usage: %s file.c\n", argv[0]); return 1; } if ((fp = fopen(argv[1], "r")) == NULL) { fprintf(stderr, "Error opening file.\n"); return 2; } cur = getc(fp); // initialise cur, assumes that the file contains at least one byte while ((next = getc(fp)) != EOF) { switch (next) { case '/': if (!state && cur == '/') { state = 2; // start of comment ignchar = 2; // don't print this nor next char (//) } else if (state == 3 && cur == '*') { state = 0; // end of block comment ignchar = 2; // don't print this nor next char (*/) } break; case '*': if (!state && cur == '/') { state = 3; // start of block comment ignchar = 2; // don't print this nor next char (/*) } break; case '\n': if (state == 2) { state = 0; ignchar = 1; // don't print the current char (cur is still in comment) } break; case '"': if (state == 0) { state = 1; } else if (state == 1) { state = 0; } } if (state <= 1 && !ignchar) putchar(cur); if (ignchar) ignchar--; cur = next; } return 0; } 
+4
source share
3 answers

Stdio files save the "eof" flag, which sets the first end of the file, and can only be reset by calling clearerr or by executing successful fseek or rewind . Thus, once getc returns EOF once, it will continue to return EOF even if new data becomes available, unless you use one of the above methods to clear the eof flag.

Some inappropriate implementations can immediately make new data available. This behavior is harmful and may violate the relevant applications.

+6
source

If the EOF flag in the stream is set, getc should return EOF (and if you keep calling getc , it should continue to return EOF ).

+1
source

Logically, I think he should return EOF forever.

getc is defined in terms of fgetc .

The getc () function should be equivalent to fgetc (), except that if it is implemented as a macro, it can evaluate the stream more than once, so the argument should never be an expression with side effects.

The documentation for fgetc says:

If the end-of-file indicator for the stream is set, or if the stream is at the end of the file, the end-of-file indicator for the stream must be set and fgetc () returns EOF.

And "located at the end of the file" can be determined by calling feof .

The documentation for feof says:

The feof () function returns a nonzero value if and only if the end-of-file indicator is set for the stream.

Therefore, if something does not happen to clear the end-of-file indicator, it should continue to return EOF forever.

+1
source

Source: https://habr.com/ru/post/1336394/


All Articles