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)非常方便。
如果我在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)非常方便。