【问题标题】:What is EOF in the C programming language?什么是 C 编程语言中的 EOF?
【发布时间】:2009-11-23 09:39:58
【问题描述】:

你如何才能看到最后的印刷品?换句话说,要为 EOF 输入什么?我检查了定义,它说EOF是-1。

如果你输入 Ctrl-D 你什么都看不到。

#include <stdio.h>

int main() {
 int c;
 while((c = getchar() != EOF)) {
  printf("%d\n", c);
 }
 printf("%d - at EOF\n", c);
}

【问题讨论】:

  • 您介意澄清一下吗?你有什么问题?
  • 我想放入 EOF 并查看 printf("%d - at EOF\n", c);
  • 和 EOF 据说是 -1,但它解释为三个字符并输出三个 1
  • @reinierpost:C 中的 EOF 是在 stdio.h 中定义的宏。

标签: c input eof


【解决方案1】:

在 Linux 系统和 OS X 上,输入导致 EOF 的字符是 Ctrl-D。对于 Windows,它是 Ctrl-Z

根据操作系统,该字符仅在它是一行中的第一个字符时才有效,即 Enter 之后的第一个字符。由于控制台输入通常是面向行的,因此在您使用 Enter 之后,系统也可能无法识别 EOF 字符。

是的,如果该字符被识别为 EOF,那么您的程序将永远不会看到实际的字符。相反,C 程序将从getchar() 获得-1

【讨论】:

  • 好的,但是 Windows 上的 Ctrl-z 和 Ctrl-D 有什么区别? Ctrl-z = EFO Ctrl-D = 杀死?
  • @Chris_45:在 Windows 上,Ctrl-Z 标记 EOF,Ctrl-D 只是 Ctrl-D(或字符 04)。 @gotch4:它是标准的(但很少使用)HTML:.
  • @Chris_45:Ctrl-D 对应于 ASCII EOT(传输结束),MS-DOS 但是使用 Ctrl-Z(ASCII SUB)来与 CP/M 兼容,Windows 继承了它。在 CP/M 中,EOF 字符实际上是文件中的一个字符,因为所有文件都必须是 128 个字符的倍数。用于表示 EOF 的字符特定于操作系统而不是编程语言。 en.wikipedia.org/wiki/End-of-file
  • 嗯,我的意思是 Ctrl-Z 和 Ctrl-C 之间的区别?不是 Ctrl-d
  • 那就这么说吧! :) Ctrl-C 通常会杀死从控制台接受输入的程序。 Ctrl-D 将标记输入的结束,但之后程序可以继续运行。
【解决方案2】:

你应该把括号改成

while((c = getchar()) != EOF)

因为“=”运算符的优先级低于“!=”运算符。然后你会得到预期的结果。你的表达式等于

while (c = (getchar()!= EOF))

您得到两个 1 作为输出,因为您正在进行比较“c!=EOF”。这将始终成为您输入的字符之一,然后是按回车键跟随的“\n”。除了最后一个比较 c 真的是 EOF 之外,它会给你一个 0。

关于 EOF 的编辑:EOF 通常为 -1,但标准不保证这一点。该标准仅在第 7.19.1 节中定义了 EOF:

扩展为整数的 EOF 常量表达式,类型为 int 和 一个负值,由 几个功能来指示 文件结束,即不再输入 来自流;

假设 EOF 等于 -1 是合理的,但是在使用 EOF 时,您不应针对特定值进行测试,而应使用宏。

【讨论】:

  • “扩展为整数常量表达式的 EOF,类型为 int 和负值”Int 是 32 位,EOF 通常在 wchar_t 值为 -1(或 65535)或char 值 -1 带有无关的 ÿ.
  • @LaurieSearn:在 C 中,EOF 实际上只是一个扩展为常量整数表达式的宏(通常在某些标头中定义为:#define EOF (-1)),因此通常为 4 个字节宽。 EOF 宏不会发出任何信号,因为它只是一个值。 getchar - 正如标准库中定义的那样 - 总是返回一个整数值,当它返回一个等效于 EOF 的值(通常为 -1)时,表明它已到达文件末尾。底层机制显然取决于你的 C 运行时,你不能真正做出任何概括性的陈述。
  • @Lucas:原谅我的死灵咆哮,同意。在 VS10 中,65535 并不是严格意义上的 int,但 2 的补码和符号位会发生一些变化,使其看起来如此。
  • 呸,不知道有一个宽版本的 EOF,正如 here 解释的那样。
【解决方案3】:

EOF 的值是一个负整数,以将其与 0 到 255 范围内的“char”值区分开来。它通常是 -1,但它可以是任何其他负数……根据 POSIX 规范,所以你不应该假设它是-1。

^D 字符是您在 UNIX/Linux 上的控制台流中键入的字符,用于告诉它以逻辑方式结束输入流。但在其他情况下(例如从文件中读取时),它只是另一个数据字符。无论哪种方式,^D 字符(表示输入结束)永远不会进入应用程序代码。

正如@Bastien 所说,如果getchar() 失败,也会返回EOF。严格来说,您应该调用ferrorfeof 来查看EOF 是代表错误还是流结束。但在大多数情况下,您的应用程序在任何一种情况下都会做同样的事情。

【讨论】:

  • 所以你永远不能让win32上的EOF进入appcode并看到最后的打印?
  • @Chris_45 - 我说的是 EOF 的含义。您的“应用程序代码”中的错误的根本原因是完全不同的——请参阅@Lucas 的答案,
【解决方案4】:

几个错别字:

while((c = getchar())!= EOF)

代替:

while((c = getchar() != EOF))

getchar() 也将返回键视为有效输入,因此您也需要对其进行缓冲。EOF 是指示输入结束的标记。通常它是一个所有位都设置的 int。


#include <stdio.h>
int main()
{
 int c;
 while((c = getchar())!= EOF)
 {
  if( getchar() == EOF )
    break;
  printf(" %d\n", c);
 }
  printf("%d %u %x- at EOF\n", c , c, c);
}

打印:

49
50
-1 4294967295 ffffffff- 在 EOF

输入:

1 2

【讨论】:

  • 您的代码中不是也有错误吗?您调用 getchar() 两次(一次在 while 循环中,一次在 if 中),所以第二个输入将丢失...
  • 之所以有效,是因为第二个 getchar() 从回车中获取了 '\n'。
  • @Heinzi 第二个 getchar() 用于从返回中捕获“\n”。这样做是为了解释 OP 在 hi 代码中的行为..
【解决方案5】:

EOF 表示文件结束。这是一个到达文件末尾的标志,并且将不再有数据。

编辑:

我的立场是正确的。在这种情况下,它不是文件的结尾。如前所述,在传递 CTRL+d (linux) 或 CTRL+z (windows) 时传递。

【讨论】:

  • 编辑不正确。短语“当 CTRL+d...[按下] 时通过”是无稽之谈。当用户键入 ctrl-D 时,输入文件被关闭,getchar 返回 EOF 表示已到达文件末尾。没有发送到进程的 EOF 字符。
  • 你是什么意思这是一个标志?它是特定的位模式吗?
  • 他的意思是正常(非IT,非数学)意义上的符号;即一个指示。狗摇尾巴表示它很高兴。
【解决方案6】:

来自终端的输入永远不会真正“结束”(除非设备断开连接),但在终端中输入多个“文件”很有用,因此保留一个键序列以指示输入结束。在 UNIX 中,击键到 EOF 的转换是由终端驱动程序执行的,因此程序不需要将终端与其他输入文件区分开来。默认情况下,驱动程序将行首的 Control-D 字符转换为文件结束指示符。要将实际的 Control-D (ASCII 04) 字符插入输入流,用户在其前面加上“引号”命令字符(通常是 Control-V)。 AmigaDOS 类似,但使用 Control-\ 而不是 Control-D。

在 Microsoft 的 DOS 和 Windows(以及 CP/M 和许多 DEC 操作系统)中,从终端读取永远不会产生 EOF。相反,程序识别源是终端(或其他“字符设备”)并将给定的保留字符或序列解释为文件结束指示符;最常见的是 ASCII Control-Z,代码 26。一些 MS-DOS 程序,包括部分 Microsoft MS-DOS shell (COMMAND.COM) 和操作系统实用程序(例如 EDLIN),将 Control-Z 视为在文本文件中标记有意义的数据的结尾,和/或在写入文本文件时将 Control-Z 附加到末尾。这样做有两个原因:

  1. 向后兼容 CP/M。 CP/M 文件系统仅以 128 字节“记录”的倍数记录文件的长度,因此按照惯例,如果有意义数据在记录的中间结束,则使用 Control-Z 字符来标记有意义数据的结束。 MS-DOS 文件系统总是记录文件的确切字节长度,因此在 MS-DOS 上从来不需要这样做。

  2. 它允许程序使用相同的代码从终端和文本文件中读取输入。

【讨论】:

    【解决方案7】:
    #include <stdio.h>
    
    int main() {
        int c;
        while((c = getchar()) != EOF) { //precedence of != is greater than =, so use braces
            printf("%d\n", c);
        }
        printf("%d - at EOF\n", c);
    }
    

    我认为这是检查 EOF 值的正确方法。 我检查了输出。

    对于 INPUT:abc 和 Enter,我得到 OUTPUT:97 98 99 10。(ASCII 值)

    对于 INPUT Ctrl-D,我得到了 OUTPUT: -1 - 在 EOF。 所以我认为 -1 是 EOF 的值。

    尝试其他输入而不是 Ctrl-D,例如 Ctrl-Z。 我认为它因编译器而异。

    【讨论】:

    • 当然,stdio.hEOF 定义为-1。但这不应该让您感兴趣,也不需要查看或打印出来。只需检查代码中的 EOF 并让编译器担心细节。
    【解决方案8】:

    为了简单起见:EOF 是一个整数类型,值为 -1。因此,我们必须使用一个整数变量来测试EOF。

    【讨论】:

      【解决方案9】:
      #include <stdio.h>
      
      int main() {
          int c;
          while((c = getchar()) != EOF) { 
              putchar(c);
          }    
          printf("%d  at EOF\n", c);
      }
      

      修改了上面的代码,让EOF更加清晰,按Ctrl+d,putchar用于打印字符,避免在while循环中使用printf。

      【讨论】:

      • 在 ubuntu 14.04 上测试
      【解决方案10】:
      int c;
      
      while((c = getchar())!= 10)
      {
          if( getchar() == EOF )
              break;
      
           printf(" %d\n", c);
      }
      

      【讨论】:

      • 不确定这个答案的目的是什么(或者为什么有些人没有解释就在 SO 上转储代码块),但请注意这里的错误:由于错误的 EOF 检查,每隔一个字符就会被丢弃逻辑。
      猜你喜欢
      • 1970-01-01
      • 2014-06-07
      • 1970-01-01
      • 2022-12-10
      • 1970-01-01
      • 2014-11-07
      • 2013-03-25
      • 1970-01-01
      • 2011-03-20
      相关资源
      最近更新 更多