C语言实现最高GPA学生信息查询,解决带空格姓名输入异常问题
问题原因分析
scanf("%s")读取带空格内容出错:scanf("%s")的默认分隔符为空格、换行、制表符,遇到这类字符就会终止当前读取,剩余内容会留在输入缓冲区被下一个输入语句读取,自然就出现姓名后半段被存入ID字段的问题。gets()跳过输入:你使用scanf("%d", &n)读取学生数量时,输入完成后按下的换行符会残留在输入缓冲区,gets()遇到换行符会直接判定本次输入结束,相当于读取到了空内容,所以看起来就像姓名输入环节被跳过了。额外提示:gets()函数已经在C11标准中被正式移除,存在严重的缓冲区溢出漏洞,禁止在生产代码中使用。
修复方案
- 每次输入完数值型内容后,手动清空输入缓冲区的残留换行符
- 使用安全的
fgets()函数读取带空格的字符串,读取后手动去掉末尾自带的换行符 - 补充标准main函数的返回值定义,符合C标准规范
修复后完整代码
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <math.h> typedef struct Student { char name[50]; char ID[10]; double GPA; }student; int main() { int n, i; student *arrStu; printf("Enter number of students: "); scanf("%d", &n); // 清空输入缓冲区残留的换行符 while(getchar() != '\n'); arrStu = (student*) malloc(n * sizeof(student)); if (arrStu == NULL) { printf("Error in allocating the data array.\n"); exit(1); } for (i = 0; i < n; i++) { printf("\nEnter student name: "); fgets(arrStu[i].name, sizeof(arrStu[i].name), stdin); // 去掉fgets读取到的末尾换行符 arrStu[i].name[strcspn(arrStu[i].name, "\n")] = '\0'; printf("Enter student ID: "); fgets(arrStu[i].ID, sizeof(arrStu[i].ID), stdin); arrStu[i].ID[strcspn(arrStu[i].ID, "\n")] = '\0'; printf("Enter student GPA: "); scanf("%lf", &arrStu[i].GPA); // 清空本次GPA输入后的残留换行符,避免下一轮循环读取姓名异常 while(getchar() != '\n'); } double max = arrStu[0].GPA; for (i = 0; i < n; i++) { if (arrStu[i].GPA > max) max = arrStu[i].GPA; } for (i = 0; i < n; i++) { if (arrStu[i].GPA == max) { printf("\nStudent has highest GPA is: %s", arrStu[i].name); printf("\nStudent ID is: %s", arrStu[i].ID); printf("\nStudent GPA is %0.2lf", arrStu[i].GPA); } } free(arrStu); return 0; }
内容的提问来源于stack exchange,提问作者Garrick Jay
相关产品推荐
相关产品推荐

