7

getline を使用してテキストの文字列を読み込もうとしています。何らかの理由で、「選択内容を入力してください」が 2 回表示されます。

Please enter your selection
Please enter your selection

無効なテキストを入力すると、再びループし、その後ループごとに 1 回だけ出力されます。

while (valid == false) {    
    cout << "Please enter your selection" << endl;
    getline (cin,selection);

    // I have a function here which checks if the string is valid and sets it to true 
    // if it is valid.  This function works fine, so I have not included it here.  The while
    // look breaks correctly if the user enters valid input.
}

なぜこれが起こっているのか、誰にも分かりますか?

ありがとうございました

4

2 に答える 2

10

おそらく、ループに入ったときに、前の操作からの入力バッファーにまだ何かが残っています。

によって取得され、getline無効であることが判明すると、ループが再び実行されます。


例として、ループに入る前に 1 文字を読み取ったとします。ただし、クック モードでは、アクションを実行する前に文字と改行を入力する必要があります。

したがって、文字を読み取ると、改行が入力バッファーに残ります。

次に、ループが開始され、改行が読み取られ、無効であると見なされるため、ループバックして実際の入力行を取得します。

もちろん、これは 1 つの可能性ですが、他にもある可能性があります。それは、そのループののコードと、それが何を処理するかに大きく依存しcinます。

その場合、次のようなものです。

cin.ignore(INT_MAX, '\n');

ループがそれを修正する前に。

または、どこでも行ベースの入力を使用していることを確認したい場合があります。


そのシナリオの動作を確認するためのコードを次に示します。

#include <iostream>
#include <climits>

int main(void) {
    char c;
    std::string s;

    std::cout << "Prompt 1: ";
    std::cin.get (c);
    std::cout << "char [" << c << "]\n";
    // std::cin.ignore (INT_MAX, '\n')

    std::cout << "Prompt 2: ";
    getline (std::cin, s);
    std::cout << "str1 [" << s << "]\n";

    std::cout << "Prompt 3: ";
    getline (std::cin, s);
    std::cout << "str2 [" << s << "]\n";

    return 0;
}

トランスクリプトとともに:

Prompt 1: Hello
char [H]
Prompt 2: str1 [ello]
Prompt 3: from Pax
str2 [from Pax]

これを見ると、プロンプト 2 の新しい入力を実際に待機するのではなく、プロンプト 1 で入力した行の残りを取得するだけであることがeわかりlます。lo\n

行のコメントを外すと、ignore期待どおりに動作します。

Prompt 1: Hello
char [H]
Prompt 2: from Pax
str1 [from Pax]
Prompt 3: Goodbye
str2 [Goodbye]
于 2012-08-10T01:30:55.790 に答える