Puts() 和 Gets() 在 scanf() 之后使用时不起作用

Puts() and Gets() does not work when used after scanf()

如果我在gets()puts()之前使用scanf()puts()gets()功能似乎不起作用。请看下面的代码。

如果我删除之前的部分,puts()gets() 可以正常工作。这是为什么?

#include <stdio.h>
#include <string.h>

int main (void)
{
    int numberOutcomes;
    char outcomeOne[50];

    printf("How many outcomes do you have on your form?\n");
    scanf(" %d", &numberOutcomes);
    printf("The number of outcomes you have on your form is %d\n", numberOutcomes);

    printf("Type in your first outcome then press Enter. For example: good outcome or bad outcome.\n");
    gets(outcomeOne);

    puts(outcomeOne);

    return 0;
}

第一条建议,不要使用 gets() - 没有 方法可以安全地使用它以避免潜在的缓冲区溢出(这是很少 甚至从 ISO 标准中删除的东西,从 C11 开始)。相反,使用 fgets(),它 可以 限制读入的内容。

至于您的特定问题,scanf(" %d", &numberOutcomes)将在跳过空格后消耗输入流中的足够字符来填充numberOutcomes 仅此而已。 重要的是,它将 不会 消耗尾随空格,例如当您按下 时放置在那里的 \n 字符ENTER 提交您的意见。

因此,在 gets() 调用中,它只会得到一个空行。

这两个 都可以通过选择 scanf() 式输入或line-based 输入。对于前一种情况,扫描下一项将(通常)跳过输入流中的空格,对于后者,读取行会读取整行,包括尾随空格。

您可以将两者混合使用,但需要更多的努力。

我的建议是对所有内容使用 line-based 输入,然后从您读取的字符串中使用 sscanf 特定数据。这具有以下优点:

  • 避免您发现的确切问题;和
  • 允许您在同一行上多次 sscanf 如果您需要处理多种行格式。

为此,rock-solid line-input 例程(如 this one)非常方便。