清除 C++ 中的輸入緩衝區

Jinku Hu 2023年10月12日
清除 C++ 中的輸入緩衝區

本文將演示如何在 C++ 中清除輸入緩衝區的多種方法。

使用 std::cin::ignore 函式清除 C++ 中的輸入緩衝區

ignorestd::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
``
作者: Jinku Hu
Jinku Hu avatar Jinku Hu avatar

DelftStack.com 創辦人。Jinku 在機器人和汽車行業工作了8多年。他在自動測試、遠端測試及從耐久性測試中創建報告時磨練了自己的程式設計技能。他擁有電氣/ 電子工程背景,但他也擴展了自己的興趣到嵌入式電子、嵌入式程式設計以及前端和後端程式設計。

LinkedIn Facebook

相關文章 - C++ IO