链表中的字符串输入 [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()