这是我的代码:
struct Patient{
char name[50];
char gender ; // M:male , F:female
unsigned age ;
unsigned Systole;
unsigned Diastole;
};
//blah blah blah
struct Patient P[3];
for(i=0 ; i<3 ; i++){
printf("\nPATIENT%d\n",i+1);
printf("Name:");
gets(P[i].name);
printf("Gender(F=female , M=male):");
scanf("%c",&(P[i].gender));
printf("Systole:");
scanf("%u",&(P[i].Systole));
printf("Diastole:");
scanf("%u",&(P[i].Diastole));
printf("\n%s %c %u %u\n", P[i].name, P[i].gender, P[i].Systole, P[i].Diastole);
}
这是我的输出:
PATIENT1
Name:Samantha
Gender(F=female , M=male):F
Systole:120
Diastole:90
Samantha F 120 90
PATIENT2
Name:Gender(F=female , M=male):Jack
Systole:Diastole:
J 4718656 131072
PATIENT3
Name:Gender(F=female , M=male):Michael
Systole:Diastole:
ack M 16454 2
Normal:0
正如您所看到的(我在获取每个结构索引数据后打印)我从用户获取输入时遇到问题。有什么问题?
修改
我将代码(由于建议)更改为:
for(i=0 ; i<3 ; i++){
printf("\nPATIENT%d\n",i+1);
printf("Name:");
scanf("%s", &(P[i].name));
printf("Gender(F=female , M=male):");
scanf("%c",&(P[i].gender));
printf("Systole:");
scanf("%u",&(P[i].Systole));
printf("Diastole:");
scanf("%u",&(P[i].Diastole));
printf("\n%s %c %u %u\n", P[i].name, P[i].gender, P[i].Systole, P[i].Diastole);
}
但输出仍然失真:
PATIENT1
Name:Alison
Gender(F=female , M=male):Systole:F
Diastole:
Alison
436170816 4044120064
PATIENT2
Name:Gender(F=female , M=male):Systole:Jack
Diastole:
F
4456512 131072
PATIENT3
Name:Gender(F=female , M=male):Systole:Sandy
Diastole:
Jack
答案 0 :(得分:1)
scanf(“%u”,&amp;(P [i] .Diastole));获取一个整数,但保留一个新行(从用户输入数字并按Enter键)
在循环的第二次迭代中,得到(P [i] .name);读取留在换行符上并从那一点开始放弃其他所有内容。
你需要处理读取最后一个新行字符(或者可能是\ r \ n),或者你可以使用获取或更好的fgets读取每行输入并使用sscanf或atoi等从中获取值(当需要一个数字时。)
答案 1 :(得分:0)
函数gets
不存储换行符,因此您必须使用:
scanf(" %c", &(P[i].gender))
请注意跳过空格的空格,包括换行符
您应该避免使用gets
函数,尝试仅使用scanf
这应该是:
scanf(" %49[^\n]%*c", P[i].name)
有关scanf如何工作的更多信息,请参阅此post
全力以赴的工作代码是:
for(i=0 ; i<3 ; i++){
printf("\nPATIENT%d\n",i+1);
printf("Name:");
scanf(" %49[^\n]%*c", P[i].name);
printf("Gender(F=female , M=male):");
scanf(" %c",&(P[i].gender));
printf("Systole:");
scanf("%u",&(P[i].Systole));
printf("Diastole:");
scanf("%u",&(P[i].Diastole));
printf("\n%s %c %u %u\n", P[i].name, P[i].gender, P[i].Systole, P[i].Diastole);
}
第一个scanf现在也消耗了上一次迭代中的任何换行符。
答案 2 :(得分:0)
你的主要问题是这句话:
scanf("%c",&(P[i].gender));
c
转换说明符不会跳过输入流中的任何前导空格(例如前一个条目后面的换行符,gets
不会消耗),这样你就可以获取性别的换行符,而这会丢掉所有其他内容。
要解决此问题,请在%c
:
scanf(" %c",&(P[i].gender));
空格告诉scanf
使用所有前导空格。
此外,请勿使用gets
- 它已在C99 TC3中弃用,并已完全从C2011规范中删除。 将在您的代码中引入故障点。请改用fgets
:
fgets( P[i].name, sizeof P[i].name, stdin );
与gets
不同,fgets
会消耗并将换行符存储到目标缓冲区(如果有空间),因此您需要检查并删除它,类似于以下内容:
char *newline = strchr( P[i].name, '\n' );
if ( newline )
*newline = 0;
答案 3 :(得分:0)
最后,我得到了真实而又整洁的答案:
scanf
函数在尝试解析字符以外的内容之前会自动删除空格。字符格式(主要是%c
)是例外;他们不会删除空格。
因为我收到性别问题,所以它引起了问题。最后我意识到使用getch()
是最好的解决方案,因为它不会将任何内容放入缓冲区并立即返回。同样getch()
是非标准的,但它出现在我的案例中
所以最后这是我的代码:
for(int i=0 ; i<3 ; i++){
printf("\nPatient%d",i+1);
printf("\nName:");
scanf("%s", P[i].name);
printf("Age:");
scanf("%u", &(P[i].age));
printf("Gender(F=female , M=male):");
P[i].gender = getchar();
printf("\nSystole:");
scanf("%u",&(P[i].Systole));
printf("Diastole:");
scanf("%u",&(P[i].Diastole));
}
我也编辑了问题标题,因为它具有误导性。谢谢大家回答。