2

ご挨拶!

今回は余分なイントロをカットして、ポイントにまっすぐに行きましょう。

isalnumメソッドを使用したC++で問題が発生しました。

コード:

int playAgainst = 0;
do
{
    cout << "Who do you want to play against?(1/2)\n";
    cout << "1: Human player\n";
    cout << "2: Computer player\n";
    cin >> playAgainst
} while(!isalnum(playAgainst) && playAgainst != 0);

コードに見られるように、私はユーザーに選択肢を提供しています。人間と対戦するか、コンピューターと対戦します。

私が欲しいのは、ユーザーが他の何かを入力する限り、整数値(cin >> playAgainst)で質問を繰り返すことです。ただし、charまたはstring値を入力すると、無限にループし続けます。100%確信はありませんが、問題がある場合は、非int値がplayAgainstの値としてすでに保存されていることは明らかです。保存する前に、入力値がintであるかどうかをコードのこのビットで確認するにはどうすればよいですか。それ?

または、char / stringとして保存してからチェックする唯一の可能性はありますか?

後者の場合、新たな問題が発生します。isalnumは、少なくとも私が知っていることから、パラメーターとしてintのみを受け入れます。その文字列または文字がintであるかどうかを確認するにはどうすればよいですか?

お読みいただきありがとうございます。そしてうまくいけば、私はすぐに答えとして返信を受け入れるでしょう^^

答えてくれてありがとう。私は欲しいものを手に入れました、そしてすべてが解決されました。

私が受け入れられた答えを選んだ理由は、まあ...最初は、それが私のコードを私が望むように機能させたからです。でも複数の答えを受け入れたいです。

4

6 に答える 6

2

を作成し、ではなくplayAgainstcharと比較します。現在、ユーザーは文字またはのASCII(または文字セットが何であれ)コードを入力する必要があります。'0'0'1''2'

isalnumを除いてint、の有効範囲外のsでは機能しません。(引数を取るという事実は、C ++とは異なる整数プロモーションルールを持つCからの残り物です。)charEOFintEOF

于 2011-03-30T11:20:47.927 に答える
2

isalnum()チェックを外します。cin >> playAgainst数値以外はすべてゼロに変換します。これは2番目のチェックで検出されます。ゼロは有効な入力ではないため、これは単なるオプションであることに注意してください。

isalnum()自分で文字を解釈している場合に便利ですが、この場合、ストリームはすでにそれを行っています。

于 2011-03-30T11:32:07.990 に答える
1

これは、コンパイラがisalnumを実装する方法です。

int isalnum (int ch)
{
  return (ch >= 'a' && ch <= 'z') || 
         (ch >= 'A' && ch <= 'Z') || 
         (ch >= '0' && ch <= '9');
}

したがって、そのコードスニペットを独自のコードで記述した方がよいでしょう。これは、インラインバージョンのisalnumと同等です。

于 2011-03-30T11:42:39.467 に答える
1

バッファをクリアしないからです。入力が無効な場合は、バッファからクリアする必要があります。そうしないと、次の入力に進むことができます。そうしないと、毎回同じ入力を抽出しようとします(同じ不正な入力であるため、失敗します)。したがって、無限ループに入ります。

于 2011-03-30T11:51:14.487 に答える
1

問題は、charではなくintを入力していることです。また、入力のテキストがintでない場合、入力は失敗します。この場合、playAgainstは変更されずstd::cin エラーを明示的にクリアするまで失敗が記憶されます。また、エラー状態のストリームからの入力はノーオペレーションです。あなたがおそらくやりたいことは

  1. 単一の文字を入力します。スペースをスキップしたくない場合は、 `std :: cin.get(ch)`または `ch = std :: cin.get()`を使用します。(後者の場合、`ch`は`EOF`も処理する必要があるため、 `int`である必要があります。一方、` :: isalnum`を直接使用できますが、`の場合は使用できません。 ch`は`char`です。
  2. 有効な入力を完全にチェックします。`::isalnum`だけでなく、入力がリスト内の正当なセレクターであるかどうかを確認します。次のようなもの:
        ch!= EOF && std :: find(legalChars.begin()、legalChars.end()、(char)ch)!= LegalChars.end()
    
  3. エラーが発生した場合は、残りの入力をすべてクリアします。たとえば、次のようにします。
               std :: cin.ignore(INT_MAX、'\ n');
    

EOF実際には、誤ったコマンドとは異なる方法で処理することをお勧めします。(の後に入力をクリアしないEOFと、他に何も読むことができなくなります。しかし、おそらく、を取得した場合EOF、それはユーザーが諦めたためであり、これ以上試してみたいとは思わないでしょう。)

最後に、次のテーブルを使用して、すべての情報を共通の場所に保持することをお勧めします。

struct Command
{
    char        op;
    char const* prompt;
    void (*     func)();
};

次に、これらのテーブルをループしてプロンプトを出力し、それを検索して文字が正当かどうかを確認し、最後に、見つかったエントリで関数を呼び出します。または、抽象基本クラス、コマンドごとにそれから派生する具象クラスを定義しstd::map<char, AbstractBase*>、マッピングなどにを使用します。非常にC ++ですが、このような単純なケースでは少しやり過ぎかもしれません。

于 2011-03-30T17:26:48.197 に答える
0

isdigit()を使用しないのはなぜですか。

于 2011-03-30T11:22:48.370 に答える