47

你怎么才能看到最后的印刷品?换句话说,要为 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);
}
4

10 回答 10

54

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

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

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

于 2009-11-23T09:51:56.140 回答
32

您应该将括号更改为

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 时,您不应针对特定值进行测试,而应使用宏。

于 2009-11-23T10:09:34.870 回答
10

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

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

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

于 2009-11-23T09:46:38.437 回答
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
<ctrl-d>
于 2009-11-23T10:10:17.380 回答
3

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

编辑:

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

于 2009-11-23T09:41:32.103 回答
3

来自终端的输入永远不会真正“结束”(除非设备断开连接),但在终端中输入多个“文件”很有用,因此保留一个键序列以指示输入结束。在 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. 它允许程序使用相同的代码从终端和文本文件中读取输入。

于 2015-04-25T16:01:55.087 回答
1
#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。我认为它因编译器而异。

于 2009-11-23T10:43:34.880 回答
0

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

于 2019-06-19T13:34:57.587 回答
-1
#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。

于 2016-06-07T06:04:38.673 回答
-3
int c;

while((c = getchar())!= 10)
{
    if( getchar() == EOF )
        break;

     printf(" %d\n", c);
}
于 2017-05-26T03:36:39.943 回答