2016-06-10 69 views
1

我剛剛瞭解鏈接列表。我爲自己寫了一個小程序,練習關於鏈表的機制。這是我第一次嘗試做一個小pokedex(實際上沒有保存任何東西)。所以我正在嘗試正確設置輸入。目前一切正常,沒有錯誤,我可以執行它。鏈接列表中的字符串輸入[C]

問題是第二次輸入的pokemon名稱不能在任何數據中讀取,而是跳過讀入並直接進入scanf函數,爲什麼會出現這種情況?

void addPokemon(void){ 

    pokemonPtr firstPtr; 
    pokemonPtr thisPokemon; 
    firstPtr = NULL; 

    firstPtr =(pokemon *) malloc(sizeof(pokemon)); 
    firstPtr->name = malloc(sizeof(char) * POKEMON_LENGTH); 

    printf ("Enter the name of the Pokemon.\n"); 
    fgets(firstPtr->name, POKEMON_LENGTH, stdin); 

的問題就在這裏,這FGETS是不是真的被執行,所以基本上不會提示用戶輸入的字符串。

printf ("Enter the number of the Pokemon.\n"); 
    scanf("%d",&firstPtr->number); 

    firstPtr->next =(pokemon *) malloc(sizeof(pokemon)); 

    thisPokemon = firstPtr->next; 

    int i = 0; 

    while (i < 10){ 

     thisPokemon->name = malloc(sizeof(char) * POKEMON_LENGTH); 

     printf ("Enter the name of the Pokemon.\n"); 
     fgets(thisPokemon->name, POKEMON_LENGTH, stdin); 
     printf ("Enter the number of the Pokemon.\n"); 
     scanf("%d",&thisPokemon->number); 

     thisPokemon->next =(pokemon *) malloc (sizeof(pokemon)); 
     thisPokemon = thisPokemon->next; 

     i++; 

    } 
+0

寫入任何其他空白空間('\0''\t'' ')'的getchar();'(對於消耗換行)後'scanf(「%d」,&firstPtr-> number);' – BLUEPIXY

+0

我不太確定這是否真的有幫助,因爲它會提示我輸入內容,但問題仍然存在。 我將在主要帖子中正確編輯問題。 –

+0

嘗試'scanf(「%d%* c」,&firstPtr-> number);'而不是'scanf(「%d」,&firstPtr-> number);' – BLUEPIXY

回答

0

fgets在讀取換行符時停止讀取。在你的例子中,stdin已經有了一個'\ n',所以fgets接受並完成了。這是因爲scanf不會讀取輸入數字時得到的換行符,而是將其留在stdin中。

兩個解決方案:

而是與fgets的,使用scanf("%s", name);。這是可行的,因爲%s將在它所需的字符串之前忽略空格和換行符。

用戶getchar()讀取換行符。

+0

太棒了! 嗯,我之前使用過scanf,但不知何故,我總是在考慮字符串時收到警告。好吧,我想我需要在結構中使用char *名稱,這真的起作用。 但我不明白的東西與getchar() –

+0

請注意,scanf將只能使用1個字口袋妖怪名稱...但所有口袋妖怪名稱是一個字我很喜歡99%肯定 – ezPaint

+0

你有一些很好的口袋妖怪知識那裏:) 我需要更改兩個或兩個以上的單詞嗎? –

0

與您的代碼的問題是很多時候,掃描語句掃描\n人物從以前的掃描語句返回......你能避免很多方法,但所有這些方法最終消費\n字符

一些的方法是:

  • scanf(" ");這個空間消耗\n字符
  • getch();同樣

    我用過的第一個在我下面的代碼。


注意:下面請務必確保進入口袋妖怪的name指定POKEMON_LENGTH。如果不是,則通過下一個掃描語句進入。

如果#define POKEMON_LENGTH 15然後,始終輸入口袋妖怪名14或更少的字符作爲第15屆空間是\0,和上面的東西會發生未定義行爲...


我已經更改了addPokemon()功能:(我在評論expalined)

void addPokemon(void) 
{ 

    pokemonPtr firstPtr; 
    pokemonPtr thisPokemon; 
    firstPtr = NULL; 

    firstPtr =(pokemon *) malloc(sizeof(pokemon)); 
    firstPtr->name = malloc(sizeof(char) * POKEMON_LENGTH); 

    printf ("Enter the name of the Pokemon.\n"); 
    fgets(firstPtr->name, POKEMON_LENGTH, stdin); 

    printf ("Enter the number of the Pokemon.\n"); 
    scanf(" %d",&firstPtr->number); //give a space to consume \n 

    firstPtr->next =(pokemon *) malloc(sizeof(pokemon)); 

    thisPokemon = firstPtr->next; 

    int i = 0; 

    while (i < 10) 
    { 

     thisPokemon->name = malloc(sizeof(char) * POKEMON_LENGTH); 

     printf ("Enter the name of the Pokemon.\n"); 
     scanf(" ");//consume white spaces or \n 
     fgets(thisPokemon->name, POKEMON_LENGTH, stdin); 
     printf ("Enter the number of the Pokemon.\n"); 
     scanf(" %d",&thisPokemon->number); 

     thisPokemon->next =(pokemon *) malloc (sizeof(pokemon)); 
     thisPokemon = thisPokemon->next; 

     i++; 

     } 
    } 
} 

最後,

爲什麼給一個空間?

通過給出一個空間,該編譯器消耗'\n'字符或從先前scanf()

+0

@ThomasChristopherDavies我希望這會帶走你的問題...我已經運行了代碼,它按預期工作 – Cherubim

+0

哦,很好,thx爲額外的輸入。現在,上面的scanf解決方案現在可以做到這一點。只要我開始嘗試將信息保存到文件中,我需要回到使用「fgets」。 你能推薦任何關於「消耗空白空間」的文獻嗎?我的意思是我完全開始明白你的意思,但我並不真正瞭解這個規則的因果關係。 我希望我能給你兩張支票,或者至少「答案是有用的」(我還沒有足夠的聲望)。 歡呼聲 –