清除 C++ 中的輸入緩衝區
本文將演示如何在 C++ 中清除輸入緩衝區的多種方法。
使用 std::cin::ignore
函式清除 C++ 中的輸入緩衝區
ignore
是 std::cin
物件的內建函式,可用於從輸入流中提取和丟棄字元,直到指定的分隔符為止。在我們討論 cin::ignore 函式的行為之前,應該注意到作為 cin
/cout
的標準輸入和輸出流是緩衝的,這意味著在使用者的寫/讀和作業系統核心的實際緩衝狀態之間有一些簿記發生。該緩衝區由 C++ 庫本身管理,其目的是使讀/寫請求更有效。請注意,為每個位元組呼叫作業系統服務將導致 CPU 資源的使用效率非常低下,因此使用中間緩衝區來累積一些請求,然後使用單個請求來呼叫作業系統。
因此,cin::ignore
可以丟棄緩衝區中的剩餘位元組,當有連續呼叫時,這些位元組可能會意外讀取。下面的示例程式碼旨在更清晰地演示忽略
行為。我們實現了一個無限的 while
迴圈,該迴圈從 cin
流中讀取三個整數並將它們儲存在相應的變數中。整數被列印到 cout
上,然後在下一次迭代中執行例程。請注意,使用者在第一次迭代中可能會提供三個以上的整數。在這種情況下,cin.ignore
之前的程式碼將僅儲存其中的 3 個,其他程式碼仍將存在於中間緩衝區中。現在,如果未使用給定引數呼叫 cin.ignore
,則下一次迭代 cin >>
行將讀取其餘輸入內容,並且將發生不一致的行為。在這種情況下,可以使用 cin.ignore
呼叫來丟棄輸入,直到遇到給定字元為止。在這種情況下,我們指定了一個換行符,通常用於緩衝 cin
流。
#include <iostream>
#include <limits>
#include <sstream>
using std::cin;
using std::cout;
using std::endl;
using std::numeric_limits;
int main() {
while (true) {
int i1, i2, i3;
cout << "Type space separated numbers: " << endl;
cin >> i1 >> i2 >> i3;
if (i1 == 0) exit(EXIT_SUCCESS);
cin.ignore(numeric_limits<std::streamsize>::max(), '\n');
cout << i1 << "; " << i2 << "; " << i3 << endl;
}
return EXIT_SUCCESS;
}
輸出(帶有示例使用者輸入):
Type space separated numbers:
12 32 54
12; 32; 54
另外,我們可以實現另一個示例程式碼,該示例程式碼接受兩個由空格分隔符分隔的字串。在這種情況下,使用者可能會提供兩個以上的名稱,這將迫使此程式碼在 2 個以空格分隔的字串之後刪除所有首字母縮寫。如果使用者輸入中只有一個名稱和一個空格,則將始終終止 cin
輸入的換行符儲存為第二個首字母。後一種行為可以通過在 << name << surname
語句之後新增單個字元輸出來證明。
#include <iostream>
#include <limits>
#include <sstream>
using std::cin;
using std::cout;
using std::endl;
using std::numeric_limits;
int main() {
char name, surname;
cout << "Type your name and surname: ";
name = cin.get();
cin.ignore(numeric_limits<std::streamsize>::max(), ' ');
surname = cin.get();
cout << "Your initials are: " << name << surname << endl;
return EXIT_SUCCESS;
}
輸出(帶有示例使用者輸入):
Type your name and surname: Lama Lime
Your initials are: LL
``