2013-08-04 44 views
0

我知道這個問題得到問百餘次,我已經走遍了所有的可能性,但我想我不夠嫺熟知道在哪裏這個問題所在。我正在編寫一個程序,我需要用數據填充結構(整數和字符串)。第一次嘗試時,它跳過了第一個,但是我沒有驚慌,因爲我記得我需要使用fflush(stdin)來克服這個問題。網站我搜索投票反對使用fflush(stdin),因爲它有未定義的行爲。他們說使用getchar()會吃額外的換行符,從而解決問題。因此,我的代碼:scanf函數都不會被跳過,即使有安全裝置(getchar函數())

int manNode(){ 
Item *p; 
int helper; 
p = (Item*)malloc(sizeof(Item)); 
printf("Welk type? (Taak:1, Examen:2, Voordracht:3)\n"); 
scanf("%u",&helper);       //selecting an itemtype 
if (helper < 1 || helper > 3) 
{ 
    printf("wrong value, please try again"); 
    return 0; 
} 
getchar();          //I've just put getchars everywhere for safety. 
p->entrytype = helper-1; 
helper = 0; 
printf("Vul een naam in:\n"); 
scanf("%s", p->name);       //this one fills in fine 
getchar(); 
printf("Vul een vaknaam in: \n"); 
scanf("%s", p->course);      //this one gets skipped if I type more than one letter in the last scanf()     
getchar(); 
printf("Vul een starttijd in:\n");    //From here on out everything gets skipped 
p->start = getTijd(); 
checkTijd(p->start);       
printf("Vul een eindtijd in: \n"); 
p->end = getTijd(); 
checkTijd(p->end); 

我知道這有點混亂,但專注於scanfs和getchars。 getTijd()也有一對scanfs掃描整數,他們也被跳過。我不知道該從哪裏出發。 (代碼不完整,剩下的只是無關緊要的)

+0

你可以顯示結構'項目? – Ishmeet

+1

'scanf'大約是最壞的分析工具,在C語言中,因爲它試圖做兩個任務(讀取輸入,並將其分解成塊),當作品是不完全如預期離開輸入流中的難 - 確定狀態。 'fgets/sscanf'使得分工更加健壯。 – msw

+0

您必須檢查每次使用scanf()時都會成功。當它出錯時,它仍然是錯誤的。你應該錯誤檢查'getchar()'函數。您還應該通過打印剛剛讀取的值來進行調試,以確保獲得您認爲的所有結果。 –

回答

0

你可以定義一個新的getchar

#include <stdlib.h> 
#include <stdio.h> 

#define getchar(x) (scanf("%c", x)) 

int main() 
{ 
    char x, y[10]; 
    getchar(&x); 
    scanf("%s", y); 
    printf("got %s\n", y); 
    return 0; 
} 

更新:這可能是一個更好的辦法

#include <stdlib.h> 
#include <stdio.h> 

void work_to_do() 
{ 
#define getchar(x) (scanf("%c", x)) 
    char x, y[10]; 
    getchar(&x); 
    scanf("%s", y); 
    printf("got %s\n", y); 
#undef getchar 
} 
int main() 
{ 
    work_to_do(); 
    return 0; 
} 

解決scanf新行無知和getchar(但仍scanf忽略空白)

#include <stdlib.h> 
#include <stdio.h> 
#include <unistd.h> 
#include <sys/types.h> 

#define __getchar() (read(2, NULL, 1)) // 2 stands for standard error, we can make the user enter a character. 

void work_to_do() 
{ 
    char y[10]; 
    __getchar(); 
    scanf("%s", y); 
    printf("got %s\n", y); 
    __getchar(); 
} 
int main() 
{ 
    work_to_do(); 
    return 0; 
} 

這是很好的看看這個: Read space-separated values from file

+1

至少,你必須在重新定義它之前'#undef getchar'。我不相信這是一個好主意。對宏使用替代名稱(可能是'GetChar')會更好。 –

+0

希望我的更新是一個更好的方法。 –

+0

問題是''通常定義一個宏'getchar()',所以在你自己定義'#define getchar'之前,你應該'#undef getchar'來取消標準版本。 –

0

scanf作爲記錄。另外,只要功能被理解,scanf就沒有錯。

我創建你的代碼的副本和蒸餾水是要突出你想要做什麼。您需要自己填寫剩下的部分。

在這段代碼,你需要輸入一個數字,然後按回車。然後輸入一個字符串並按回車等。注意。該fflush(stdout)語句是每ķ& R.標準C實現fflush迫使緩衝區的內容輸出到控制檯的一部分。這種沖洗使用戶/計算機對話框合理。

#include <stdio.h> 
main() 
{ 
    char string[100]; 
    int helper; 

    printf("Welk type? (Taak:1, Examen:2, Voordracht:3)\n"); 
    fflush(stdout); 

    scanf("%d",&helper); //select an itemtype 
    if (helper < 1 || helper > 3) 
    { 
     printf("wrong value, please try again"); 
     return 0; 
    } 

    printf("Vul een naam in:\n"); 
    fflush(stdout); 

    scanf("%s", &string[0]); 
    printf("\n%s\n", string); 

    printf("Vul een vaknaam in: \n"); 
    fflush(stdout); 

    scanf("%s", &string[0]); 
    printf("\n%s\n", string); 

    printf("Vul een starttijd in:\n"); 
    fflush(stdout); 
    scanf("%s", &string[0]); 
    printf("\n%s\n", string); 

    printf("Vul een eindtijd in: \n"); 
    fflush(stdout); 
    scanf("%s", &string[0]); 
    printf("\n%s\n", string); 
} 

此代碼在Eclipse上運行,帶有Microsoft C編譯器。

此外,讓我強調,如果您輸入:1 AAA BBB CCC DDD並按下輸入,然後scanf將執行五次。在這個例子中,代碼會運行完成!

所以,你需要跟蹤你的代碼邏輯(在這種情況下,直線)看scanfs如何基於輸入什麼數據調用。

希望這會有所幫助。請詢問是否有更多問題。

+0

對於微不足道的輸入而言,這被破壞了。如果您回答「Vul enn naam in:」與任何數量的退貨,那麼'scanf'永遠不會返回。 – msw