是否在返回EOF后定义了getc()?

我用getc(); 在C练习中,在回顾程序后,我发现了一些奇怪的东西。 我假设在命令行参数上给出的文件至少包含一个字节。 (它连续两次调用getc();没有检查EOF 。在空文件上尝试它之后它仍然顺利运行。我的问题是: getc();的行为是否已经用完了文件指针(EOF有已经达到并且未被复活)未定义或是否会继续返回EOF?

我想我可以将这个问题扩展到C STL中的所有I / O函数,请在你的答案中澄清这一点。

这是该程序的代码。 该程序应该从所有注释中剥离C / C ++源文件(并且它完美地工作)。

 #include  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; } 

Stdio文件保留一个“eof”标志,该标志在第一次到达文件结束时设置,并且只能通过调用clearerr或执行成功的fseekrewind带来重置。 因此,一旦getc返回EOF一次,它将继续返回EOF ,即使新数据可用,除非您使用上述方法之一清除eof标志。

一些不符合的实现可以立即使新数据可用。 此行为是有害的,可能会破坏符合要求的应用程序。

如果设置了流上的EOF标志,则getc应该返回EOF (如果你继续调用getc ,它应该继续返回EOF )。

从逻辑上讲,我认为应该永远回归EOF

getc是根据fgetc定义的。

getc()函数应该等效于fgetc(),除非它作为宏实现,它可以多次评估流,因此参数永远不应该是具有副作用的表达式。

fgetc的文档说:

如果设置了流的文件结束指示符,或者流是在文件结尾,则应设置流的文件结束指示符,并且fgetc()将返回EOF。

并且“在文件结尾处”可以通过调用feof来确定。

feof的文档说:

当且仅当为流设置了文件结束指示符时,feof()函数才返回非零。

因此,除非发生某些事情以清除文件结束指示符,否则它应该继续永久返回EOF