当我的程序从Linux上的标准输入读取CTRL-D时,为什么它不能转换为EOF?

时间:2012-04-03 04:09:14

标签: c linux eof

以下是我写的程序。

/*******************************************************************************
 * This program reads EOF from standard input stream to store in an integer 
 * variable and in a character variable. Both values are then output to see the
 * stored value as integer.
*******************************************************************************/
#include<stdio.h>

int main (void)
{
    /* Local Declarations */
    int        num;
    char       ch;

    /* Read EOF as character & integer and display values stored */
    printf("\nPlease only input EOF for all input prompts below");
    printf("\nNumber? ");
    scanf("%d", &num);
    printf("\nThat integer input converts to %d", num);
    printf("\nCharacter? ");
    scanf(" %c", &ch);
    printf("\nThat character input converts to %d", ch);

    /* Check if any of the stored values are recognized as EOF */
    if(num == EOF)
        printf("\nNumber is an EOF");
    if(ch == EOF)
        printf("\nCharacter is an EOF");

    /* Exit Program */
    printf("\n");
    return 0;
}// main()

我在Ubuntu 11.10上使用gcc编译。它无法识别程序中的EOF Ctrl - D ,并在尝试打印其值时输出0。我终端上面程序的输出如下。

Please only input EOF for all input prompts below
Number? 
That integer input converts to 0
Character? 
That character input converts to 0

注意:当我按下两个输入时,CTRL-D不会被终端回显,因此在上述程序执行中不可见。

我已经读过EOF在stdio.h和stdlib.h中定义为整数,传统上定义为-1。此外,我知道 Ctrl - D 模拟标准输入的EOF。那么为什么在将它存储到整数变量时它不会转换为-1?

2 个答案:

答案 0 :(得分:4)

因为scanf("%d")将尝试读取表示数字的字符,然后将其存储到给定变量中。

如果关闭流,它会EOF存储到该号码中。否则,你如何区分文件结尾和输入EOF(-1)的数值。

scanf将返回扫描的项目数(如果格式错误,则为零;如果流关闭或发生某些错误,则返回EOF)。它将此作为scanf函数的返回码返回, not 通过传递给它的指针变量返回。

如果来自scanf的返回值告诉您,您应该只考虑变量(您在地址中传递的变量)。

换句话说,你正在寻找类似的东西:

int rc = scanf ("%d", &num);
switch (rc) {
    case EOF: {
        printf ("EOF returned\n");
        break;
    }
    case 0: {
        printf ("No items scanned\n");
        break;
    }
    default: {
        printf ("Scanned %d\n", num);
        break;
    }
}

答案 1 :(得分:2)

来自the docs

“如果输入在第一次匹配失败或转换之前结束,则返回EOF。如果发生读取错误,则设置流的错误指示符,返回EOF”

请注意,它会被返回,而不是被读入您传递的指针。

要区分错误和EOF,您可以使用feof