5

アップデート

問題の原因を見つけました。私は魚の殻を実験してきました。誰かが私のコードをMacで正常に実行したというコメントを見て、標準のbashシェルで試してみることにしました。それは完璧に機能しました。だから、これ以上魚の殻はないと思います。:)

cinがどのように、そしてなぜそのように機能するのかを知っていただければ幸いです。これが私の質問の主要部分です。


私はよくある問題に遭遇しました:cinループで使用すること。コードは単純ですが、解決策が見つかりません。Googleが提供してくれた答えはさまざまですが、通常は、、、の組み合わせが含まcin.clear()cin.ignore()ますcin.get()。残念ながら、問題を解決する組み合わせや順序を見つけることができませんでした。さらに、の機能を完全に理解していないのはイライラしますcin。これを修正するために試行錯誤を使用したくありません。何が起こっているのかを正確に理解したい。

何が起こるべきか

コードを実行すると、オプションのリストを含むプロンプトが表示されます。オプションの1つを実行する文字を入力できるはずです。次に、プロンプトが再度表示され、[終了]オプションを選択するまでプロセスを繰り返します。

実際に何が起こるか

コードを実行するとすぐに、プロンプトが画面に任意の回数印刷され、最終的にプロンプ​​トの途中で停止します。それから私は何もすることができませんが、でそれを殺します^C

$ ./run

Choose an option:
[A]dd a score
[R]emove a player
[E]xit

    : That is not a valid input.

[repeated a bunch of times]

Choose an option:
[A]dd a score
[R]emove a player
[E]xit

    : That is not a valid input.


Choose ^C
$ 

私の質問

何がシンにそれをさせるのですか?経験豊富なJava開発者(ただし、初心者のC ++開発者)として、私はバッファーやストリームなどの概念に精通していますが、どのようにcin機能するのかわかりません。私はそれcin.clear()がエラー状態をクリアcin.ignore()し、ストリーム内のいくつかの文字を無視することを知っています。私のGoogle-fuは、これまでのところ簡潔な参照を見つけることができませんでした。

なぜcinそれがするように行動するのですか?cinループで使用するときに内部で何が起こるかをどのように視覚化する必要がありますか?この無限のメニューのアイデアをC++で実装するための最もエレガントな方法は何ですか?

私のコード

これが私のコードの簡略化されたバージョンであり、フルバージョンとまったく同じ問題が発生します。

#include <iostream>

using namespace std;

int main () {

    //infinite menu 
    char input;
    while(true) {

        //prompt
        cout << "\n\nChoose an option:\n";
        cout << "[A]dd a score\n";
        cout << "[R]emove a player\n";
        cout << "[E]xit\n";
        cout << "\n\t: ";

        //input
        cin >> input;

        //decide what the input means
        switch(input) {
            case 'a':
            case 'A':
                cout << "Add a score.\n";
                break;
            case 'r':
            case 'R':
                cout << "Remove a player.\n";
                break;
            case 'e':
            case 'E':
                cout << "Program Complete.\n";
                return 0;
                break;
            default:
                cout << "That is not a valid input.\n";
        }
    }
    return 0;
}

私はコンパイルして実行します:

$ g++ Test.cpp -o run
$ ./run

gcc version 4.2.1 (Based on Apple Inc. build 5658) (LLVM build 2336.11.00)Mac OSX10.8.2で実行しています。

4

1 に答える 1

6

自分に有利に働き、から直接トークンを抽出しないでくださいstd::cin。代わりに、を使用して1行ずつ読み取り、各行をgetline解釈しますまた、ブールコンテキストで入力操作の結果を常に評価する必要があります。そうしないと、任意の入力を正しく処理できなくなります。

テストの場合、を呼び出すとプログラムが存続する必要がありますecho "abc" | ./run。これは常に最初のテストの1つである必要があります。

次に、コードについて説明します。

#include <string>
#include <iostream>

int main()
{
    for (std::string line; std::getline(std::cin, line); )
    {
        if (line.empty()) { continue; }


        if (line == "A" || line == "a") { /* ... */ continue; }

        if (line == "R" || line == "r") { /* ... */ continue; }

        if (line == "E" || line == "e") { break; }

        std::cout << "Sorry, I did not understand.\n";
    }

    std::cout << "Goodbye!\n";
}
于 2012-10-30T23:34:24.030 に答える