求助,如果我写了我想要4个输入(学生),并且在写了3个名字之后,它给出了输出,我不能写第4个。
#include <stdio.h>
struct Student{
char name[100];
float weight;
};
int main(){
int n,i;
struct Student people[100];
printf("Enter how many you want: ");
scanf("%d",&n);
for(i=0;i<n;i++){
fgets(people[i].name, sizeof(people[i].name), stdin);
}
for(i=0;i<n;i++){
printf("%s",people[i].name);
}
}
[scanf
和fgets
或scanf
与许多其他get输入功能的组合,这是一个非常普遍的问题。
您在控制台中键入的输入将被写入stdin
缓冲区,并且scanf
从该缓冲区读取。这也是为什么您将stdin
作为第三个参数传递给fgets
的原因,这是在告诉fgets
从哪里读取数据。
[从stdin
缓冲区中读取数据时,它会被消耗,请想象一下,就好像您是ctrl x
文本一样。
不同的输入函数以不同的方式和限制使用此数据。使用scanf( "%d", &integer_variable );
告诉scanf
从该缓冲区读取一个int
。
[您可以认为,无论如何,这就是我想要的,这就是我对此提供的投入,您会误会。
[当您键入一些数字并按回车键时,您不仅在发送数字,而且也在发送回车。您在控制台中看到的5
实际上是5\n
,其中\n
(换行符)来自return/enter
键。遇到-在这种情况下- scanf
时,\n
停止读取,并将\n
留在缓冲区中,它不会消耗它。
在调用fgets
之后调用scanf
时,运行的第一个fgets
会消耗该\n
字符,并停止读取。 (fgets
如果出现a\n
遇到字符]也将停止此时,people[0].name
仅包含\n
字符。您的第一个输入实际上写在第一个索引中,即数组的第二个位置。您认为您正在输入第一个字符串,而程序正在接收第二个字符串。这就是为什么您的输入少于给定输入的原因。
可能有很多解决方案和解决方法。
起初您可能不会使用scanf
,使用时可能会遇到更多类似这样的意外问题,而无所适从。
您可以在getchar()
之后呼叫scanf
以消耗剩余的\n
您可以将对scanf
的呼叫修改为scanf( "%d%*c", ... )
,"%*c
在消费了char
后将丢弃任何int
。
但是要注意,这两个都假定您将在缓冲区中等待一个额外的字符,如果您编写的代码不会发生这种情况,那么调用这些代码本身会产生问题。
请勿使用fflush(stdin)
,刷新输入缓冲区是C中未定义的行为。
[当您询问用户他想要多少时,在按下Enter键后,此Enter键处于标准输入中,而当i为0时,fgets()首次将其作为输入。为了进行验证,您可以在循环内打印i,也可以观察到在打印名称时第一行为空白。解决方法是冲洗标准输入。参见下面的程序,我仅在代码中添加一行。
#include <stdio.h>
struct Student{
char name[100];
float weight;
};
int main(){
int n,i;
struct Student people[100];
printf("Enter how many you want: ");
scanf("%d",&n);
fflush(stdin); // to clear standard input
for(i=0;i<n;i++){
fgets(people[i].name, sizeof(people[i].name), stdin);
}
for(i=0;i<n;i++){
printf("%s",people[i].name);
}
}