问题描述
在这里,如果我不使用 getchar()
,输出会出现异常:
getchar()
到底在做什么?
在调用另一个输入之前它会保持什么?
在这种情况下如何调用下一个输入?
我的代码:
//To take 3 students data using stucture which is user defined.
#include<stdio.h>
#include<stdlib.h>
//#include<conio.h>
struct student
{
char reg_number[200];
char name[200];
int marks_obt;
};
int main()
{
struct student stud1,stud2,stud3;
printf("Enter registration number of student 1 : ");
gets(stud1.reg_number);
printf("Enter name of student 1 : ");
gets(stud1.name);
printf("Enter marks of student 1 : ");
scanf("%d",&stud1.marks_obt);
system("cls");
//getchar();
printf("Enter registration number of student 2 : ");
gets(stud2.reg_number);
printf("Enter name of student 2 : ");
gets(stud2.name);
printf("Enter marks of student 2 : ");
scanf("%d",&stud2.marks_obt);
system("cls");
//getchar();
printf("Enter registration number of student 3 : ");
gets(stud3.reg_number);
printf("Enter name of student 3 : ");
gets(stud3.name);
printf("Enter marks of student 3 : ");
scanf("%d",&stud3.marks_obt);
system("cls");
printf("ID of student 1 is %s \n Name of student 1 is %s \n Marks obtained by stdent 1 is %d",stud1.reg_number,stud1.name,stud1.marks_obt);
printf("\n\n");
printf("ID of student 2 is %s \n Name of student 2 is %s \n Marks obtained by stdent 2 is %d",stud2.reg_number,stud2.name,stud2.marks_obt);
printf("\n\n");
printf("ID of student 3 is %s \n Name of student 3 is %s \n Marks obtained by stdent 3 is %d",stud3.reg_number,stud3.name,stud3.marks_obt);
//getch();
}
解决方法
首先,never use the gets()
。它已从 C 和 C++ 标准中弃用。安全的方法是应用 fgets()
:
char input[128];
if (fgets(input,sizeof input,stdin) == NULL) {
// Oops... input was incorrectly given,handle the error
return EXIT_FAILURE; // To quit
}
// Removing the trailing newline character
input[strcspn(input,"\n")] = 0;
在下一次 gets()
调用中要求用户提供其他输入时,您遇到了重叠问题,因为您在使用 {{1} 完成输入时也按下了 Return 键}.最后添加一个换行键。
scanf()
接受换行符,因此它被丢弃并完成您期望的工作。
已经有评论和正确答案应该足够了,但是从您的上一条评论来看,您似乎还不明白发生了什么。
这一行:
scanf("%d",&stud1.marks_obt);
解析一个整数,为此你按 Enter,当你这样做时,一个 \n
被添加到 stdin
缓冲区,并保持在那里,它不是被scanf
解析的。
之后:
gets(stud2.reg_number);
将解析该 \n
字符并将其存储在 stud2.reg_number
中,然后程序继续运行。
当您使用 getchar()
时,它会解析 \n
并再次将 stdin
缓冲区留空,因此 gets
没有任何内容可解析并等待您的输入,从而更正问题,它仍然是一个脆弱的解决方案,但它适用于这种特殊情况。
故事的寓意,至少不要将 scanf
与 gets
、fgets
混用,因为如前所述,gets
已从 C11 的标准中删除。有些编译器还支持它的原因超出了我的理解。