关于输入:C编程语言中的EOF是什么?

What is EOF in the C programming language?

您如何查看最后的打印? 换句话说,要为EOF输入什么? 我检查了定义,并说EOF为-1。

如果输入Ctrl-D,您将看不到任何内容。

1
2
3
4
5
6
7
8
9
10
11
#include <stdio.h>

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


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

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

是的,如果该字符被识别为EOF,则您的程序将永远看不到实际的字符。而是,C程序将从getchar()获取-1


您应该将括号更改为

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

因为" ="运算符的优先级低于"!="运算符。然后您将获得预期的结果。你的表情等于

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

您将获得两个1,因为您正在进行比较" c!= EOF"。对于输入的字符,它将始终成为一个字符,然后按回车键将成为" n"。除了最后一个比较,其中c确实是EOF之外,它会为您提供0。

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

EOF which expands to an integer
constant expression, with type int and
a negative value, that is returned by
several functions to indicate
end-of-file, that is, no more input
from a stream;

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


EOF的值是一个负整数,以区别于0到255范围内的" char"值。它通常是-1,但是根据POSIX规范,它可以是任何其他负数...不应该假设它为-1。

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

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


几个错别字:

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

代替:

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

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <stdio.h>
int main()
{
 int c;
 while((c = getchar())!= EOF)
 {
  if( getchar() == EOF )
    break;
  printf(" %d
"
, c);
 }
  printf("%d %u %x- at EOF
"
, c , c, c);
}

印刷品:

1
2
3
49
50
-1 4294967295 ffffffff- at EOF

用于输入:

1
2
3
1
2
<ctrl-d>


EOF表示文件结束。这表明已到达文件末尾,并且将不再有数据。

编辑:

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


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

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

  • Backward compatibility with CP/M. The CP/M file system only recorded the lengths of files in multiples of 128-byte"records", so by convention a Control-Z character was used to mark the end of meaningful data if it ended in the middle of a record. The MS-DOS filesystem has always recorded the exact byte-length of files, so this was never necessary on MS-DOS.

  • It allows programs to use the same code to read input from both a terminal and a text file.


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


    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    #include <stdio.h>

    int main() {
        int c;
        while((c = getchar()) != EOF) { //precedence of != is greater than =, so use braces
            printf("%d
    "
    , c);
        }
        printf("%d - at EOF
    "
    , c);
    }

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

    对于INPUT:abc,然后输入Enter我得到OUTPUT:97 98 99 10.(ASCII值)

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

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


    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    int c;

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

         printf(" %d
    "
    , c);
    }

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    #include <stdio.h>

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

    修改了上面的代码以更清楚地了解EOF,请按Ctrl + d,然后使用putchar来打印char,避免在while循环中使用printf。