【问题标题】:scanf not reading inputscanf不读取输入
【发布时间】:2011-03-13 13:07:41
【问题描述】:

我阅读了更多关于 scanf 的帖子,并找到了一些没有帮助我的答案:

while(!comanda){
    int tmp;
    if (scanf("%d", &tmp) == 0)
        getchar();
    else{
        comanda = tmp;
        fprintf(stdout,"%d",&comanda);
        fflush(stdout);}
    }
}

问题是在这行代码执行之后,什么都没有发生。在此之后,我对未执行的“comanda”进行了检查。

【问题讨论】:

  • fprintf(stdout,"%d",&comanda); - & 不应该在那里。顺便说一句。
  • 请更具体一些。当您说“什么都没有发生”时,代码在哪里停止?它在哪里阻塞?
  • 已编辑。现在应该说得通了。
  • “comanda”最初等于什么?
  • 最初命令它等于零。 scanf 在缓冲区中使用换行符或类似的东西是一个问题。

标签: c scanf


【解决方案1】:

scanf 和所有格式化输入函数的问题之一是终端倾向于在line mode or cooked mode 中运行,并且 API 是为原始模式设计的。换句话说,scanf 实现通常不会返回,直到遇到换行符。输入是缓冲的,以后对scanf 的调用将消耗缓冲的行。考虑以下简单程序:

#include <stdio.h>

int main() {
    int a_number;
    printf("Enter a number: ");
    fflush(stdout);
    while (scanf("%d", &a_number) != EOF) {
        printf("you entered %d\n", a_number);
        printf("Enter another number: ");
        fflush(stdout);
    }
    return 0;
}

您可以在按 return 之前输入多个数字。下面是一个运行这个程序的例子。

bash$ gcc foo.c
bash$ ./a.out
Enter a number: 1 2 3 4 5 6 7 8 9 10<Return>
you entered 1
Enter another number: you entered 2
Enter another number: you entered 3
Enter another number: you entered 4
Enter another number: you entered 5
Enter another number: you entered 6
Enter another number: you entered 7
Enter another number: you entered 8
Enter another number: you entered 9
Enter another number: you entered 10
Enter another number: <Ctrl+D>bash$ 
bash$

scanf 的每次调用都从输入流中读取一个数字,但第一次调用直到我按下return 后才返回。剩余的调用立即返回而不会阻塞更多输入,因为输入流已被缓冲,它可以从流中读取另一个整数。

对此的替代方法是使用fgets 并一次处理整行数据或使用the terminal interface 禁用"canonical input processing"。大多数人使用fgets,因为 POSIX 的终端接口部分在 Windows 下没有实现。

【讨论】:

    【解决方案2】:

    您的 scanf("%d", &amp;tmp) 可以返回 3 个值之一

    • 如果返回1,则表示读取了一个值并将其放入tmp
    • 如果它返回0,则表示缓冲区中有错误字符(您可以检测到并使用下一个getchar() 删除)
    • 如果返回EOF,则表示stdin处于文件结束状态。无论您执行多少getchar()s,“文件结束”条件都不会消失,您会陷入无限循环。

    同时测试 scanf 的返回值是否为 EOF。

    while(!comanda){
        int tmp;
        int ret;
        ret = scanf("%d", &tmp);
        if (ret == 0)
            getchar();
        else if (ret == EOF){
            perror("stdin end-of-file");
            break; /* get out of the loop */
        }
        else {
            comanda = tmp;
            fprintf(stdout,"%d",comanda); /* & is an error */
            fflush(stdout);}
        }
    }
    

    或者,甚至更好,重做您的程序以使用fgets() 读取整行并使用sscanf() 解析它。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-02-15
      • 1970-01-01
      • 1970-01-01
      • 2018-08-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多