2016-06-10 89 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”。 你能推荐任何关于“消耗空白空间”的文献吗?我的意思是我完全开始明白你的意思,但我并不真正了解这个规则的因果关系。 我希望我能给你两张支票,或者至少“答案是有用的”(我还没有足够的声望)。 欢呼声 –