2017-11-27 11 views
0

これは基本的に私はこのループを今日では約7時間働いています。それは私がそれがどのようにすべきか振る舞いません。 cin(行はcharですが、列はintです。したがって、たとえばa1の代わりにaa1を入力すると、新しいcoordを要求する前にinvalidCoordが2回呼び出されます)。do ... whileループは私が欲しいものを表示していません

do 
{ 
    confirmShot = false; 
    validShot = false; 
    failShot = false; 
    cout << enterCoord; 
    cin >> row >> column; 
    if (cin.fail()) 
    { 
     cin.clear(); 
     cout << invalidCoord << endl; 
     failShot = false; 
     continue; 
    } 
    if (failShot == true) 
    { 
     row = toupper(row); 
     xCoord = column - 1; 
     yCoord = static_cast<int>(row - 'A'); 
     if(xCoord > 9 || xCoord < 0 || yCoord > 9 || yCoord < 0) 
     { 
      cout << invalidCoord << endl; 
      validShot = false; 
     } 
     else 
     { 
      validShot = true; 
     } 
    } 
    else 
    { 
     continue; 
    } 
    currentTile = tileToSymbol(computerBoard[xCoord][yCoord]); 
    if (validShot == true) 
    { 
     switch(currentTile) 
     { 
      case '~': 
      case 'a': 
      case 'b': 
      case 's': 
      case 'd': 
      case 'p': 
       cout << "You have already shot at " << row << column << "." << '\n' 
        << "Please pick a new coordinate!" << endl; 
       validShot = false; 
       confirmShot = false; 
       break; 
      default: 
       confirmShot = true; 
     } 
    } 
    else 
    { 
     continue; 
    } 
} 
while(!confirmShot); 

出力:

Your shot: Enter the coordinates for a shot (e.g. B2) cc2 
Invalid coordinates! 
Pick a row value between A and J 
and a column value between 1 and 10. 
Enter the coordinates for a shot (e.g. B2) Enter the coordinates for a shot (e.g. B2) cc2 
Invalid coordinates! 
Pick a row value between A and J 
and a column value between 1 and 10. 
Enter the coordinates for a shot (e.g. B2) Enter the coordinates for a shot (e.g. B2) c2 
Enter the coordinates for a shot (e.g. B2) c2 

また、私はループはもう終了している間...やる取得する方法を見つけ出すことはできません。それは、誰かが2番目の文字として非整数を入力した場合に、フェイルステートを処理しなければならないことに気付く前に、正常終了していました。

私が話していた誰かが次のセクションにスキップする必要があると言い、プログラムをロックすると、プログラムがロックアップします。そこにコンティニューコードがあり、うまくいきました。

私は本当にこのループを正しく動作させる必要がありますが、私は自分の能力を使い果たしました。 failstateを処理してinvalidCoordを2回表示させてもいいですか(正直なところ、それはなぜ起こっているのかわかりません)、有効なエントリを受け取った後にループを終了してその日を保存しますか?

+0

私はその行がcharであり、列がintであることを記事で述べました。 完全なコードはここにあります: https://repl.it/repls/DiscreteAltruisticNighthawk – Ernesto

+0

私はあなたが 'cin.clear()'がしていることを誤解していると思います。エラーフラグをクリアするだけです。無効な入力はまだそこにあります。あなたがしたいと思っているようなことをするコードを書いているのは好きではありません。入力行を読み込み、それに2文字だけ含まれているかどうかを確認しますか? –

+0

入力に '>>'を使わないでください。基本的に 'scanf'です。 – melpomene

答えて

1

私はそれを単純化しすぎている可能性があります。私が間違っている場合はコメントしてください。単にif文に誤りがあると思います。

failShotがfalseに初期化されたため、if (failShot == true)が呼び出されないように見え、if (cin.fail())をチェックするたびに、再びfalseとして更新されます。これを正しく理解している場合は、cinが失敗しない場合はif (failShot == true)が呼び出されます。この場合、failShotをTrueに初期化するとエラーが修正されます。

は変更してみてください:

failShot = false; 

へ:

failShot = true; 
+0

これは私が見ていた問題の1つでしたが、エラー状態の後でも「無効な座標」を表示して残りの部分を実行するバグを取り除こうとしていましたが、まるでエラー状態がなく、do ... whileループを終了したかのように、ループの私は、コードの小さな部分だけを明示的に実行するようにプログラムを分離しようとしていましたが、途中で残りの部分を実行しないように指示していました。 – Ernesto

+0

それでは、ループを終了しないでください**。 'confirmShot'が真である場合にのみ終了し、' validShot'が真であれば 'confirmShot'は真になり、' failShot'が真である場合には有効ショットが真となります。 loop endless –

+0

あなたは問題をひとつ明らかにしようとしたようですが、別の問題が発生しました。元のエラー/出力を表示して戻すことをお勧めします。それから、どうやって助けてくれるのかが分かります –

0

OK、あなたの問題はstd::cinオブジェクトの理解です。それは、キーボードバッファから文字を取り出すように入力した文字を解析中にエラーが発生したときに、この位置を増分位置pos_type p = -1

std::cin開始する仕組み

これは、そのように、eofの位置を設定します次回実行時にはeofを返し、何もしません。消費するstd::cinニーズを意味している

// when you enter for expel: c1 - which is correct input, it prints 
p = 2; // advanced two position in the buffer until EOF 
// when you enter wrong input: cc1 - it prints 
p =-1; 
// next run just after the error message, it will print 
p = 3;//this number is the number of character read last time and it coincide with EOF 
// right after, it will prompt you for another input 

(唯一興味深い部分がここに印刷された)出力を以下になるcin<<row<<column;

cin << row << column ; 
cout << "p =" << cin.tellg(); 

:下のこのスニペットを挿入し、あなたのコードでこれを説明するため

バッファ内のすべての文字が-1に設定され、文字の抽出が再開されます。

これは、メッセージが重複している理由です。どのようにそれを修正するには?

これは醜いハックです:

//inside the loop under 
cin.clear() 
cin.seekg(0); // rewind...uuurrrgg, ugly!! but it works 

私が提案する何をあなたのコードを再構築することです。ブール論理を使用して、美しいコードフローチャートを設計します。このようなコードベースのエラーは、コードがよく書かれたコードではなくスパゲッティコードであることを意味します。

頑張ってください!

関連する問題