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

Jinku Hu 2021年4月29日
清除 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 <sstream>
#include <limits>

using std::cout; using std::endl;
using std::cin; 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 <sstream>
#include <limits>

using std::cout; using std::endl;
using std::cin; 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
``
Author: Jinku Hu
Jinku Hu avatar Jinku Hu avatar

Founder of DelftStack.com. Jinku has worked in the robotics and automotive industries for over 8 years. He sharpened his coding skills when he needed to do the automatic testing, data collection from remote servers and report creation from the endurance test. He is from an electrical/electronics engineering background but has expanded his interest to embedded electronics, embedded programming and front-/back-end programming.

LinkedIn

相關文章 - C++ IO