Thread: problem with cin.fail() in if/else clause

  1. #1
    Registered User
    Join Date
    Apr 2010
    Posts
    1

    problem with cin.fail() in if/else clause

    Hello,

    I am writing an assignment for a tic-tac-toe game. I am trying to use cin.fail() in an if/else clause to check for invalid input. In my code, I use if( cin.fail() ), then cin.clear(), then while( cin.get() != '\n' ) ; to clear the input buffer. Then I have an else block. I am using cin to get an integer. If I enter just letters for input (which should change cin to the fail state), everything works fine. However, if I enter a number followed by a letter (which should also change cin to the fail state), the execution jumps directly to the else block, cycles back to the beginning of the program loop, and then prints my error message again as if the letter had never been removed from the input buffer. The if block I am referring to starts at line 78. The else block follows at line 97. I have tried (and commented out) cin.ignore(80), and while( cin.get(ch) && ch != '\n' ) ; , as well to clear the input buffer. I do not understand why it is jumping to the else block after entering the if block on condition of cin.fail(). My doing cin.clear() should not cause it to do this should it? I have included some cout statements that help you see the flow of execution. Please, can somebody help me?

    If the input is invalid, such as "6a", I don't want it to assign the tic-toe-board's position #6, as it is doing now. The assignment statement for the positions of the board is in the else block, and this should not be executing if cin.fail() was true, correct? Please help.
    Code:
    #include<iostream>
    #include<cstdlib>
    #include<iomanip>
    #include<cstdio>
    
    int main() {
       bool validInput = false;
       bool winner = false;
       bool boardFull = false;
       char player[2];
       char board[3][3][2];
       int input = 0, x, y, p = 0;
       player[0] = 'X';
       player[1] = 'O';
       // populate board array with numbers 1-9
       int count = 1;
       for( x=0; x < 3; x++ ) {
          for( y=0; y < 3; y++, count++ )
             sprintf( board[x][y], "%d", count );
       }
       while( validInput == false || ( winner == false && boardFull == false ) ) {
          // display board
          system("clear");
          std::cout << "beginning of loop\n";
          for( x=0; x < 3; x++ ) {
             std::cout << std::endl;
             for( y=0; y < 3; y++ )
                std::cout << std::setw(5) << board[x][y];
          }
          // check each horizontal row to see if there is a winner
          for( x=0, y=0; x < 3; x++, y=0 ) {
             while( y < 2 && board[x][y][0] == board[x][y+1][0] )
                y++;
             if( y == 2 )
                winner = true;
          }
          // check each vertical column to see if there is a winner
          for( x=0, y=0; y < 3; y++, x=0 ) {
             while( x < 2 && board[x][y][0] == board[x+1][y][0] )
                x++;
             if( x == 2 )
                winner = true;
          }
          // check downward diagonal to see if there is a winner
          x = y = 0;
          while( x < 2 && board[x][y][0] == board[x+1][y+1][0]) {
             x++;
             y++;
          }
          if( x == 2 )
             winner = true;
          // check upward diagonal to see if there is a winner
          x = 2;
          y = 0;
          while( x && board[x][y][0] == board[x-1][y+1][0] ) {
             x--;
             y++;
          }
          if( !x )
             winner = true;
          if( winner == true )
             std::cout << "\n\nPlayer " << player[!p] << " has won the game.\n\n";
          else {
             // check to see if board is full
             x = 0;
             y = 3;
             for( x=0; x < 3 && y == 3; x++ ) {
                for( y=0; y < 3 && ( board[x][y][0] == 'X' || board[x][y][0] == 'O' ); y++ )
                   ;
             }
             if( x == 3 && y == 3 ) {
                boardFull = true;
                std::cout << "\n\nThe board is full. Stalemate. Game Over.\n\n";
             }
             else {
                std::cout << "\n\nPlayer " << player[p] << ", enter your choice from 1-9.\n";
                std::cin >> input;
                if( std::cin.fail() || input < 1 || input > 9 ) {
                   // clear fail flag so can use cin again
                   std::cin.clear();
                   // flush keyboard input buffer
    //               char ch;
                   while( std::cin.get() != '\n' )
                      ;
    //               std::cin.ignore(80);
    //               while( std::cin.get(ch) && ch != '\n' )
    //                  ;
                   std::cout << "\nYou must enter a number from 1-9.\n";
                   // set input back to an invalid value so if, say it was
                   // assigned the '6' from input such as "6a"
                   std::cout << "input is being assigned 0\n";
                   input = 0;
                   std::cout << "input is now " << input << std::endl;
                   p = !p;
                   system("read");
                }
                else {
                   for( x=0, count=1; x < 3; x++ ) {
                      for( y=0; y < 3; y++, count++ ) {
                         if( count == input ) {
                            if( board[x][y][0] == 'X' || board[x][y][0] == 'O' ) {
                               std::cout << "\nThat place has already been taken."
                                             << "Choose a different one.\n\n";
                               p = !p;
                               system("read");
                            }
                            else {
    			   validInput = true;
                               std::cout << "board array is assigned. input is "
                                             << input << " and count is " << count << std::endl;
                               system("read");
                               board[x][y][0] = player[p];
                            }
                         }
                      }
                   }
                }
             }
          }
          // switch players
          p = !p;
          std::cout << "gone through loop\n";
          system("read");
       }
    }

  2. #2
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    Quote Originally Posted by clearcom View Post
    However, if I enter a number followed by a letter (which should also change cin to the fail state),
    This does not match the reality. As long as the input begins with a number, the input will succeed.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Need help understanding a problem
    By dnguyen1022 in forum C++ Programming
    Replies: 2
    Last Post: 04-29-2009, 04:21 PM
  2. Memory problem with Borland C 3.1
    By AZ1699 in forum C Programming
    Replies: 16
    Last Post: 11-16-2007, 11:22 AM
  3. Someone having same problem with Code Block?
    By ofayto in forum C++ Programming
    Replies: 1
    Last Post: 07-12-2007, 08:38 AM
  4. A question related to strcmp
    By meili100 in forum C++ Programming
    Replies: 6
    Last Post: 07-07-2007, 02:51 PM
  5. WS_POPUP, continuation of old problem
    By blurrymadness in forum Windows Programming
    Replies: 1
    Last Post: 04-20-2007, 06:54 PM