链表中的字符串输入 [C]
string input in linked list [C]
我刚学链表。我自己写了一个小程序来练习链表的机制。这是我第一次尝试做一个小图鉴(实际上没有保存任何东西)。所以我正在尝试正确设置输入。目前一切正常,没有错误,我可以执行它。
问题是第二次输入宝可梦名字时没有读入任何数据,而是跳过读入直接进入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++;
}
fgets 在读取换行符时停止读取。在您的示例中,stdin 中已经有一个 '\n',因此 fgets 接受它并完成。这是因为 scanf 不会读取您输入数字时得到的换行符,而是将其留在标准输入中。
两种解决方案:
使用 scanf("%s", name);
而不是 fgets。这是有效的,因为 %s
将忽略白色 space 和字符串之前的换行符。
使用 getchar() 读取换行符。
你的代码问题很多次,扫描语句正在扫描 \n
从以前的扫描语句返回的字符......你可以通过多种方式避免它,但所有这些方式最终都会消耗 \n
字符
其中一些方式是:
scanf(" ");
这个space消耗了\n
字符
getch();
类似
我在下面的代码中使用了第一个。
注意 : 始终确保输入name
以下指定POKEMON_LENGTH
的神奇宝贝。如果不是,则被下一个扫描语句接收。
if, #define POKEMON_LENGTH 15
那么,始终输入口袋妖怪名称 14
或更少的字符,因为第 15 个 space 是 [=20=]
,任何超过该字符的字符都会调用未定义的行为。 ..
我已经对您的 addPokemon()
函数进行了更改:(我已经在评论中进行了解释)
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++;
}
}
}
最后,
Why to give a space?
By giving a space,the compiler consumes the '\n'
character or any other white space ('[=23=]'
,'\t'
or ' '
) from the previous scanf()
我刚学链表。我自己写了一个小程序来练习链表的机制。这是我第一次尝试做一个小图鉴(实际上没有保存任何东西)。所以我正在尝试正确设置输入。目前一切正常,没有错误,我可以执行它。
问题是第二次输入宝可梦名字时没有读入任何数据,而是跳过读入直接进入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++;
}
fgets 在读取换行符时停止读取。在您的示例中,stdin 中已经有一个 '\n',因此 fgets 接受它并完成。这是因为 scanf 不会读取您输入数字时得到的换行符,而是将其留在标准输入中。
两种解决方案:
使用 scanf("%s", name);
而不是 fgets。这是有效的,因为 %s
将忽略白色 space 和字符串之前的换行符。
使用 getchar() 读取换行符。
你的代码问题很多次,扫描语句正在扫描 \n
从以前的扫描语句返回的字符......你可以通过多种方式避免它,但所有这些方式最终都会消耗 \n
字符
其中一些方式是:
scanf(" ");
这个space消耗了\n
字符getch();
类似我在下面的代码中使用了第一个。
注意 : 始终确保输入name
以下指定POKEMON_LENGTH
的神奇宝贝。如果不是,则被下一个扫描语句接收。
if, #define POKEMON_LENGTH 15
那么,始终输入口袋妖怪名称 14
或更少的字符,因为第 15 个 space 是 [=20=]
,任何超过该字符的字符都会调用未定义的行为。 ..
我已经对您的 addPokemon()
函数进行了更改:(我已经在评论中进行了解释)
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++;
}
}
}
最后,
Why to give a space?
By giving a space,the compiler consumes the
'\n'
character or any other white space ('[=23=]'
,'\t'
or' '
) from the previousscanf()