2011-03-13 105 views
1

我读到scanf函数更多的线程,我发现一些答案的机器人没有帮助我:SCANF不读输入

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

的问题是,这个代码行得到执行后,没有任何反应。在此之后,我检查了不执行的“comanda”。

+3

你的问题是什么? – Mat 2011-03-13 13:09:33

+1

'fprintf(stdout,“%d”,&comanda);''''不应该在那里。就像旁注一样。 – dialer 2011-03-13 13:10:42

+0

请更具体。当你说“什么都没有发生”时代码停止在哪里?它在哪里阻塞? – Mat 2011-03-13 13:19:03

回答

2

一个与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; 
} 

您可以按回报之前输入多个号码。这是一个运行这个程序的例子。

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每次调用从输入流中读取一个单一的数字,但在第一次调用才回来之后,我按下回报。剩余的调用立即返回,不会阻塞更多的输入,因为输入流被缓冲,并且可以从流中读取另一个整数。

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

0

scanf("%d", &tmp)可以返回3个值

  • 如果它返回1这意味着被读取,并放置在TMP
  • 一个值,如果它返回0这意味着有在缓冲器的错误字符的一个(其你检测并摆脱下一个getchar()
  • 如果它返回EOF这意味着stdin是在文件结束的条件。不管你做了多少次,“文件结束”状态都不会消失,而且你陷入了无限循环。

还测试从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()解析它。