1

I'm still quite new to c++ and just experimenting with the language.

I have recently created a 'tictactoe' game.

I have created this simple looking function to get the users board position (from 1 to 9). It seems to work fine but I found a weird bug so to call it;

Whenever I enter a 12 digit number or higher the loop just carries on forever printing 'Invalid position!' and on to the next line 'Choose your position 1-9: '.

I am using visual studio to write code. Is it something with the code or is it perfectly fine? I'm eager to find out to learn from it.

Here's the function:

int getUserPosition()
{
    int position;
    while (true)
    {
        cout << " Choose your position 1-9: " << endl;
        cin >> position;
        if (position < 1 or position > 9)
        {
            cout << "Invalid position!" << endl;
        }
        else if (board[position - 1] == 'X')
        {
            cout << "This position has been taken!" << endl;
        }
        else
        {
            return position;
            break;
        }
    }
}
11
  • 5
    You should not be "experimenting" with C++. That does not tend to end well. Learn the basics from a good book first. Commented May 8, 2018 at 23:05
  • 6
    Test the stream state after cin >> position; You have no idea whether or not you read good data. If you read bad data, you want to discard the bad data and clear the error flags before continuing. Something like if (cin >> position) { do stuff with position } else { clean up bad input } Commented May 8, 2018 at 23:07
  • 3
    Don't use >> for user input. It has the same problems as scanf. Also, code after return is unreachable. Commented May 8, 2018 at 23:08
  • 5
    @SzczureX "I prefer to learn from project and from the mistakes" What I'm getting at is mainly that there are a lot of mistakes that appear to work anyway, but are still Undefined Behavior. Some of those mistakes are very subtle. Also, chances are you'll teach yourself bad practices, as the good way to do things is not always trivial to find through trial and error. Commented May 8, 2018 at 23:19
  • 3
    Have you used a debugger to investigate what's happening? If you prefer hands-on learning, a debugger is a necessity. Commented May 8, 2018 at 23:25

1 Answer 1

3

I finally understand the actual behavior here. This is not invoking undefined behavior but rather defined behavior you don't want.

cin >> position;

This tried to read your 12 digit number, which didn't fit into an int, so the read failed. Because it failed on a format error, the 12 digit number remained in the buffer, so the next pass around the loop tried to read it again.

Always use cin::getline() when you intend to read keyboard input. The error/cleanup logic in cin is not designed to resync keyboard input, but rather to resync input piped from a generator that can't read your error messages. In the future, when you try to use cin with a pipe, the best solution is to check cin::fail() and bail the program if it ever gets set.

Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.