首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

C++ struct 含 string 陣列輸入失敗?清除緩衝區換行符

     編輯:程式設計綜合問答

問題現象

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++ 控制台輸入不再踩坑。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved