cin >> d_number; // 讀取整數,留下 '\n' 在緩衝區
getline(cin, p[i].name); // 直接讀到殘留的 '\n',以為輸入空字串而返回
導致第一次 getline 讀取空白,後續輸入全亂。
operator>> 讀取格式化輸入後,不會消耗結尾的換行符,殘留在 stdin 緩衝區。getline 遇到換行符即停止並丟棄該換行符,導致讀到空行。
cin.ignore() 清除單一換行(最常用)cin >> d_number;
cin.ignore(numeric_limits<streamsize>::max(), '\n'); // 丟棄至換行符為止
for (int i = 0; i < d_number; ++i) {
cout << "Input the name of the donater: ";
getline(cin, p[i].name); // 正常讀取整行含空格
cout << "Input the number: ";
cin >> p[i].number;
cin.ignore(numeric_limits<streamsize>::max(), '\n'); // 每次 >> 後都要清
}
getline + stringstream 解析string line;
getline(cin, line);
d_number = stoi(line);
for (int i = 0; i < d_number; ++i) {
cout << "Input the name of the donater: ";
getline(cin, p[i].name);
cout << "Input the number: ";
getline(cin, line);
p[i].number = stod(line); // 或 stringstream 解析
}
template <typename T>
T readNumber() {
T val;
cin >> val;
cin.ignore(numeric_limits<streamsize>::max(), '\n');
return val;
}
// 使用
d_number = readNumber<int>();
p[i].number = readNumber<double>();
getline + 解析),徹底避免格式化輸入與行讀取混用的緩衝區問題。operator>> 後立即呼叫 cin.ignore(),養成肌肉記憶。<limits> 以使用 numeric_limits<streamsize>::max(),確保清除任意長度的殘留字元。struct Donation {
std::string name;
double number;
};
// 主程式
int main() {
cout << "Input the number of donater: ";
int d_number = readNumber<int>();
Donation *p = new Donation[d_number];
// ... 輸入迴圈 ...
delete[] p; // 記得釋放
return 0;
}
掌握「格式化輸入留換行、getline 吃換行」這一核心機制,C++ 控制台輸入不再踩坑。