2009-11-23 117 views
31

你如何看到最后一张照片?换句话说,要为EOF投入什么?我检查了定义,它说EOF是-1。什么是C编程语言中的EOF?

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

#include <stdio.h> 

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

你介意澄清一下吗?你的问题是什么? – qrdl 2009-11-23 09:41:39

+0

我想放进EOF并看到printf(“%d - at EOF \ n”,c); – 2009-11-23 09:45:41

+0

和EOF被认为是-1,但它解释为三个字符并且输出三个1的 – 2009-11-23 09:46:41

回答

40

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

根据操作系统的不同,只有该字符是行上的第一个字符,即后的第一个字符,才能使用输入。由于控制台输入通常是面向行的,因此系统可能无法识别EOF字符,直到您按照输入

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

+0

好的,但在Windows上Ctrl-z和Ctrl-D有什么区别? Ctrl-z = EFO Ctrl-D = kill? – 2009-11-23 10:14:28

+0

@ Chris_45:在Windows上,Ctrl-Z标记EOF,Ctrl-D只是Ctrl-D(或字符04)。 @ gotch4:标准(但很少使用)HTML:< kbd >。 – 2009-11-23 11:50:16

+1

@ Chris_45:Ctrl-D对应于ASCII EOT(传输结束),但MS-DOS使用Ctrl-Z(ASCII SUB)与CP/M兼容,并且Windows继承该选项。在CP/M中,EOF字符实际上是文件中的一个字符,因为所有文件必须是128个字符的倍数。用于信号EOF的字符特定于操作系统而非编程语言。 http://en.wikipedia.org/wiki/End-of-file – Clifford 2009-11-23 14:15:11

4

EOF表示文件结束。这是一个迹象表明文件已到达,并且不再有数据。

编辑:

我认错。在这种情况下,它不是文件的结尾。如前所述,它在CTRL + d(linux)或CTRL + z(窗口)传递时传递。

+1

-1:它可能意味着发生错误。 – 2009-11-23 09:43:27

+0

编辑不正确。短语“CTRL + d ...被按下时传递”是无稽之谈。当用户输入ctrl-D时,输入文件关闭,'getchar'返回EOF,表示文件已到达。没有发送到进程的EOF字符。 – 2013-01-09 22:47:52

+0

你是什么意思这是一个标志?它是一种特定的位模式吗? – 2015-01-11 12:09:36

7

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

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

As @Bastien说,如果getchar()失败,EOF也会返回。严格地说,您应该调用ferrorfeof来查看EOF是表示错误还是流结束。但在大多数情况下,您的应用程序在任何情况下都会执行相同的操作

+0

所以你永远不能让win32上的EOF使它到应用代码并看到最后一个打印? – 2009-11-23 09:53:00

+0

@ Chris_45 - 我正在谈论EOF的含义。在你的“appcode”中的bug的根本原因是完全不同的 - 参见@卢卡斯的回答, – 2009-11-23 21:33:12

+0

在stdio.h中有'#define EOF(-1)' – 2016-01-23 12:36:37

26

您应该将括号改为

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

+4

我们有一个赢家。 – Pod 2009-11-23 11:02:39

+1

很好的补充关于并不总是-1 ..大多数人忽视 – 2009-11-23 14:24:28

+0

“扩展为整数常量表达式,类型为int和负值的EOF”“Int”是32位,EOF信号通常取决于wchar_t值-1(或65535)或char值-1与一个无关* * *。 – 2016-01-23 04:25:23

4

夫妇错别字:

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

代替:

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

另外的getchar()把一个返回键为有效输入,所以你需要缓冲它too.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- at EOF

输入:

 
1 
2 
<ctrl-d> 
+2

您的代码中是否存在错误?你调用'getchar()'两次(一次在while循环中,一次在if中),所以第二个输入将会丢失。 – Heinzi 2009-11-23 10:48:56

+0

你测试过这个工作吗?你正在调用getchar两次.. – Pod 2009-11-23 11:03:47

+0

它的工作原理是因为第二个getchar()从返回得到'\ n'。 – Lucas 2009-11-23 11:11:23

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的值正确方法。 我检查了输出。

输入:ABC和输入我OUTPUT:97 98 99 10(ASCII值)

输入按Ctrl-d我OUTPUT:-1 - 在EOF。 所以我认为-1是EOF的值。

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

+1

当然,'stdio.h'将'EOF'定义为'-1'。但这不应该让你感兴趣,也不需要看它或打印出来。只需在代码中检查EOF,并让编译器担心细节。 – 2009-11-23 11:57:38

3

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

在微软的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. 它允许程序使用相同的代码从终端和文本文件读取输入。

-1
#include <stdio.h> 

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

改性上面的代码,得到更清楚地说明EOF,按下Ctrl + d和的putchar用于打印用printf while循环内的炭避免。

+0

在Ubuntu 14.04上测试过 – 2016-06-07 06:08:32

-1
int c; 

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

    printf(" %d\n", c); 
}