C++中cin读取结构体字符串异常,仅能正确获取一次学生姓名
代码问题排查与修复
你的C++程序存在几处明显逻辑错误,导致只能正常处理一次学生信息,下面是具体问题和修复方案:
1. 输入缓冲区残留换行,导致姓名读取异常
用cin >>读取分数后,输入缓冲区会残留换行符,下一次getline会直接读取这个空换行,导致第二个学生的姓名被跳过。解决办法是每次读取姓名前,先清空缓冲区里的换行符。
2. 内层循环变量误用(核心问题)
adder函数里的两个内层for循环,错误地使用了外层循环的i作为循环条件和增量,应该改用内层的j:
- 读取分数的循环:原代码
for (int j = 0; i < 6; i++)→ 修改为for (int j = 0; j < 6; j++) - 计算总分的循环:原代码
for (int j = 0; i < 6; i++)→ 修改为for (int j = 0; j < 6; j++)
3. 最高分查找函数死循环
comparer函数里写了index++,这会导致循环永远无法终止,应该改为i++来遍历每个学生。
修复后的完整代码
#include <iostream> #include<string> #include <limits> // 用于清空输入缓冲区 using namespace std; struct record { string name; int marks[6]; int total=0; }; int index = 5; record recorder[5]; void adder(record a[], int index) { for (int i = 0; i < index; i++) { cout << "Enter the Student Name:\n"; // 清空缓冲区中残留的所有换行符 cin.ignore(numeric_limits<streamsize>::max(), '\n'); getline(cin, a[i].name); // 遍历6门科目读取分数 for (int j = 0; j < 6; j++) { cout << "Enter the " << j+1 << " Subject Marks: "; cin >> a[i].marks[j]; } // 计算当前学生总分(先重置避免残留值干扰) a[i].total = 0; for (int j = 0; j < 6; j++) { a[i].total += a[i].marks[j]; } } } int comparer(record a[],int index){ int i=0; int totalfn =0; // 遍历所有学生查找最高总分 while (i < index) { if (a[i].total > totalfn) { totalfn = a[i].total; } i++; } return totalfn; } void toppercalc(record a[] , int index ,int topper){ cout << "\nTop student is: "; for (int i = 0; i < index; i++) { if (topper == a[i].total) { cout << a[i].name; return; } } cout << "No student found!"; } int main() { adder(recorder,index); int topper = comparer(recorder,index); toppercalc(recorder ,index , topper); return 0; }
额外优化说明
- 添加
<limits>头文件,用于调用numeric_limits清空输入缓冲区。 - 读取分数时将科目序号改为
j+1,从1开始显示更符合用户使用习惯。 - 计算总分前重置
total为0,避免结构体默认值或垃圾数据干扰结果。
内容的提问来源于stack exchange,提问作者Umar Ahmed
相关产品推荐
相关产品推荐

