2009-09-15 102 views
20

我正在使用以下C代码从用户处获取输入,直到发生EOF,但是问题是此代码无法工作,它会在首次输入后终止。任何人都可以告诉我这个代码有什么问题。提前致谢。在C中检测EOF

float input; 

printf("Input No: "); 
scanf("%f", &input); 

while(!EOF) 
{ 
    printf("Output: %f", input); 
    printf("Input No: "); 
    scanf("%f", &input); 
} 
+3

注意:假设用户输入不被管道输送,检查EOF可能是不理想的,因为这个都通常,这意味着用户必须按ctrl + d退出,这是不明显的 – Brian 2009-09-15 18:41:33

回答

40

EOF只是一个具有值(通常为-1)的宏。您必须针对EOF进行测试,例如getchar()调用的结果。

测试流结束的一种方法是使用feof函数。

if (feof(stdin)) 

注意的是,国家“流的末尾”只会后设置失败的读取。

在你的例子中,你应该检查scanf的返回值,如果这表明没有字段被读取,那么检查文件结束。

+2

谢谢Charles Bailey。 – itsaboutcode 2009-09-15 18:46:44

+3

并注意Brian的评论:stdin通常不会注册EOF,因为用户可以输入的内容总是更多。在Unixy系统上,这通常意味着control-D。 – 2009-09-15 19:08:21

+0

这取决于你的意思是我的'通常'。如果您已重定向标准输入(文件或管道,unix或窗口),EOF通常会正确发送信号。在一个交互式的unix终端中^ D通常工作,在windows文本模式下,一行开头的^ Z起作用。 – 2009-09-15 19:12:19

8

EOF是C中的常量。您没有检查EOF的实际文件。您需要这样做

while(!feof(stdin)) 

这是feof的文档。您也可以检查返回值scanf。它返回已成功转换项目的数量,如果达到文件末尾,则返回EOF

+0

FILE函数是否包含比使用EOF更好的测试变量?看起来好像在实际的文件指针上检查一个状态会比使用一些只有一半时间的奇怪函数更好。 – MarcusJ 2015-07-13 07:42:09

0

为出发点,你可以尝试用

while(!feof(stdin)) 
4

的另一个问题是,你只scanf("%f", &input);阅读更换

while(!EOF) 

。如果用户输入的内容不能被解释为C浮点数,如“pi”,则scanf()调用不会将任何内容分配给input,并且不会从那里进行。这意味着它会试图继续阅读“pi”,并失败。

鉴于while(!feof(stdin))哪些其他海报正确推荐,如果您键入“pi”,将出现无限循环打印出前值input并打印提示,但该程序不会处理任何新的输入。

scanf()返回分配给它所输入变量的数量。如果它没有赋值,那意味着它没有找到一个浮点数,并且您应该阅读更多的输入,例如char string[100];scanf("%99s", string);。这将从输入流中移除下一个字符串(最多99个字符,无论如何 - 多余的char用于字符串上的空终止符)。

你知道,这让我想起我讨厌scanf()的所有原因,以及为什么我用fgets()代替,然后用sscanf()解析它。

-1

你想检查scanf()的结果,以确保有一个成功的转换;如果没有,则三件事情之一是真实的:

  1. scanf()窒碍对%f转换说明符无效的字符(即,某些不是数字的东西,点,'e'或'E');
  2. scanf()检测到EOF;
  3. scanf()在读取stdin时检测到错误。

实施例:

int moreData = 1; 
... 
printf("Input no: "); 
fflush(stdout); 
/** 
* Loop while moreData is true 
*/ 
while (moreData) 
{ 
    errno = 0; 
    int itemsRead = scanf("%f", &input); 
    if (itemsRead == 1) 
    { 
    printf("Output: %f\n", input); 
    printf("Input no: "); 
    fflush(stdout); 
    } 
    else 
    { 
    if (feof(stdin)) 
    { 
     printf("Hit EOF on stdin; exiting\n"); 
     moreData = 0; 
    } 
    else if (ferror(stdin)) 
    { 
     /** 
     * I *think* scanf() sets errno; if not, replace 
     * the line below with a regular printf() and 
     * a generic "read error" message. 
     */ 
     perror("error during read"); 
     moreData = 0; 
    } 
    else 
    { 
     printf("Bad character stuck in input stream; clearing to end of line\n"); 
     while (getchar() != '\n') 
     ; /* empty loop */ 
     printf("Input no: "); 
     fflush(stdout); 
    } 
} 
+1

清除行结束时可能出现无限循环。我建议'while(((ch = getchar())!= EOF)&&(ch!='\ n'))/ * void * /;''然后检查(再次)EOF并设置''moredata = 0;'' – pmg 2009-09-15 19:58:45

+0

请打开一个新问题。 – andig 2018-01-22 07:46:29

-2
while(scanf("%d %d",a,b)!=EOF) 
{ 

//do ..... 
} 
+0

我已经使用这个.... – 2015-08-02 11:37:20

+0

最新错误:/我不明白 – 2015-08-02 11:37:53