为什么我需要在我的循环条件中包含 EOF?

Why do I need to include EOF in my loop condition?

我接到一个任务,要编写一个程序,该程序将接受键盘输入(不包括 space)并打印到 .txt 文件,而不使用数组。

我尝试使用 while 循环来执行此操作,但遇到了无限循环,然后我遇到了堆栈溢出并在另一个问题中找到了解决方案,EUREKA!

添加:

&& ch != EOF 

解决了我的问题。

但是,我不完全理解为什么该解决方案有效,希望帮助理解为什么需要第二个条件。

while((ch=getchar()) != '\n' && ch != EOF)
   {
       putc(ch, fin);
   }
   fclose(fin);
   return 0;

谢谢。

因为getchar的return值是读取成功的字符,并且 EOF 出错或到达文件末尾时:

man getchar

RETURN VALUE

fgetc(), getc() and getchar() return the character read as an unsigned char cast to an int or EOF on end of file or error.

stdin 可能到达文件末尾的原因有多种:

  • 用户按下 Ctrl+D(在 Unix/Linux 上)导致 stdin 关闭
  • stdin 连接到管道 ($ cat file.txt | ./myprogram) 并且管道 已关闭,因为 cat 结束。
  • stdin 连接到重定向 ($ ./myprogram < file.txt) 并且它 已到达 file.txt
  • 的结尾

在所有这些情况下,getchar 最终会 return EOF 而你无法保留 读。如果你这样做

while((ch=getchar()) != '\n')
{
    ...
}

stdin 关闭,然后你最终陷入无限循环,als EOF != '\n' 总是 评估为真。因此,为了保护自己免受这种情况的影响,您必须检查 如果读取操作失败。你通过检查读数是否 函数 returned EOF。这就是为什么

int ch;
while((ch=getchar()) != '\n' && ch != EOF)
{
    ...
}

是用getchar循环的正确方法。还要注意 ch 必须是 输入 int.

另请注意,这适用于 所有 FILE 缓冲区(以读取模式打开), 不仅 stdin.