可能重复:
Dev-C++ Input skipped
我试图使用fgets从stdin读取一个字符串数组,但是我想要读取的第一个字符串总是被忽略。是什么导致了这个问题?
#include <stdio.h>
int main()
{
int i;
struct material
{
char name[30];
float price, kg;
};
unsigned m,nr;
printf("Lorry capacity=");
scanf("%u", &m);
printf("Number of materials=");
putchar('\n');
scanf("%u", &nr);
struct material list[nr];
for (i=0; i<nr; i++)
{
printf("Name=");
fgets(list[i].name, 30, stdin);
}
putchar('\n');
for (i=0; i<nr; i++)
{
printf("%s ", list[i].name);
}
return 0;
}
答案 0 :(得分:2)
scanf("%u", &nr);
struct material list[nr];
for (i=0; i<nr; i++)
{
printf("Name=");
fgets(list[i].name, 30, stdin);
scanf("%u", &nr);
将换行符留在输入缓冲区中,因此fgets
找到一个空行而无需输入更多输入。
由于这个原因(其中包括),混合(f)scanf
和fgets
通常是一个坏主意。
作为快速修复,在第一个fgets
之前清空输入缓冲区,
int ch;
while((ch = getchar()) != EOF && ch != '\n');
if (ch == EOF) {
// oops
}
更原则性的修复方法是在使用fgets
获取整行(包括换行符)之前读入值,并使用strtoul
或sscanf
解码数字。
答案 1 :(得分:1)
这是一个非常常见的错误。使用scanf读取数字后,按ENTER键输入的换行符将保留在输入缓冲区中,因此第一次调用fgets将读取仅包含该换行符的(非常短的)行。
答案 2 :(得分:1)
我注意到我可以通过getchar()
读取输入缓冲区中剩下的换行符。
另外,我必须使用以下代码从fgets()输入中删除尾随换行符:
char *pos;
if ((pos=strchr(Name, '\n')) != NULL)
*pos = '\0';
答案 3 :(得分:0)
通常被误解的一件事是,当您要求用户提供输入时,您将获得免费赠品。
当计算机询问材料数量时:
材料数量=
51
输入“51”,你真正得到三个字符:'5'
,'1'
和'\n'
。点击回车键时,所有内容都会带有换行符。
从用户获取输入的不同实用程序处理这种不同。 fgets()
将读取换行符,然后将输入存储为"51\n"
。如果您使用scanf()
的字符串格式标识符"%s"
将其作为字符串读取,则只会获得数字"51"
,并且新行字符将保留在stdin
缓冲区中。
因此,在您的情况下,您通过scanf
读取了一个数字:
scanf("%u", &nr);
离开换行符,然后当您尝试执行下一行读取时:
fgets(list[i].name, 30, stdin);
fgets
选择该换行并存储它。
所以这里有一堆修复,一个是仅使用fgets()
,另一个是在每次扫描后使用getchar()
消耗换行符,选择由您决定。
BTW:您可以在printfs中插入换行符:printf(“材料数量= \ n”);
答案 4 :(得分:-1)
你可以在每次scanf之后做一个fgets,然后吃掉待处理的换行符:
char dummy[10];
...
scanf (...);
fgets (dummy, 1, stdin);