C++中获取cname、camount用户输入的for循环提前退出,问题出在哪?
问题原因分析
- 第一个问题是
cin >> size执行后,用户输入数字按下的换行符会残留在输入缓冲区,第一次执行getline时会直接把这个空换行读取为第一个贡献者的姓名,你以为是第一次输入姓名的环节,实际上已经是第二次读取操作了 - 第二个问题是当你输入带空格的"Asha R"时,此时程序正等待读取double类型的
camount,字符串无法转换为double,cin流会进入失败状态,后续所有输入操作直接跳过,循环直接终止
修复方案
- 在
cin >> size语句后添加清空缓冲区逻辑,清理残留的换行符 - 删除
getline(cin,conarr[i].cname)后面的.get()调用,这个调用会吃掉姓名的最后一个字符,属于多余操作 - 读取完金额后保留换行清理逻辑,避免下一次
getline读取到空行
修改后完整代码
#include <iostream> #include <string> #include <limits> // 新增头文件,用于安全清空输入缓冲区 using namespace std; struct contribution { string cname; double camount = 0.0; }; int main () { int size = 0; //get array size from user cout << "How many members do you want to enter" << endl; cin >> size; // 新增:清空输入缓冲区残留的所有字符直到遇到换行符 cin.ignore(numeric_limits<streamsize>::max(), '\n'); //create dynamic array of contribution structure contribution * conarr = new contribution[size]; for (int i=0; i < size; i++) { cout << "Enter name: " ; getline(cin, conarr[i].cname); // 去掉多余的.get() cout << "Enter contribution amount: "; (cin >> conarr[i].camount).ignore(numeric_limits<streamsize>::max(), '\n'); // 清空金额输入后的残留换行 } // 测试输出验证读取结果 cout << "\n录入完成,信息如下:" << endl; for (int i = 0; i < size; i++) { cout << "姓名:" << conarr[i].cname << ",捐款金额:" << conarr[i].camount << endl; } delete[] conarr; return 0; }
补充说明
如果不想引入额外头文件,也可以用cin.ignore()替代上面的全量清空逻辑,只要保证能吃掉换行符即可,全量清空的写法兼容性更强,不会因为缓冲区有其他残留字符导致问题。
内容的提问来源于stack exchange,提问作者Asha Richardson
相关产品推荐
相关产品推荐

