2011-03-13 136 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()解析它。