Scanf skips every other while loop in C

2018-12-31 04:54发布

I'm trying to develop a simple text-based hangman game, and the main game loop starts with a prompt to enter a guess at each letter, then goes on to check if the letter is in the word and takes a life off if it isn't. However, when I run the game the prompt comes up twice each time, and the program doesn't wait for the user's input. It also takes off a life (one life if it was the right input, two if it wasn't), so whatever it's taking in isn't the same as the previous input. Here's my game loop, simplified a bit:

while (!finished)
{
    printf("Guess the word '%s'\n",covered);

    scanf("%c", &currentGuess);

    i=0;
    while (i<=wordLength)
    {
        if (i == wordLength)
        {
            --numLives;
            printf("Number of lives: %i\n", numLives);
            break;
        } else if (currentGuess == secretWord[i]) {
            covered[i] = secretWord[i];
            secretWord[i] = '*';
            break;
        }
        ++i;
    }

    j=0;
    while (j<=wordLength)
    {
        if (j == (wordLength)) {
            finished = 1;
            printf("Congratulations! You guessed the word!\n");
            break;
        } else {
            if (covered[j] == '-') {
                break;
            }
        }
        ++j;

        if (numLives == 0) {
            finished = 1;
        }

    }
}

I assume the problem is scanf thinking it's taken something in when it hasn't, but I have no idea why. Does anyone have any idea? I'm using gcc 4.0.1 on Mac OS X 10.5.

标签: c gcc scanf
10条回答
刘海飞了
2楼-- · 2018-12-31 05:25

Just a guess, but you are inputting a single character with scanf, but the user must type the guess plus a newline, which is being consumed as a separate guess character.

查看更多
骚的不知所云
3楼-- · 2018-12-31 05:25

Jim and Jonathan have it right.

To get your scanf line to do what you want (consume the newline character w/o putting it in the buffer) I'd change it to

scanf("%c\n", &currentGuess);

(note the \n)

The error handling on this is atrocious though. At the least you should check the return value from scanf against 1, and ignore the input (with a warning) if it doesn't return that.

查看更多
临风纵饮
4楼-- · 2018-12-31 05:26

Break the problem up into smaller parts:

int main(void) {
    char val;
    while (1) {
        printf("enter val: ");
        scanf("%c", &val);
        printf("got: %d\n", val);
    }
}

The output here is:

enter val: g
got: 103
enter val: got: 10

Why would scanf give you another '10' in there?

Since we printed the ASCII number for our value, '10' in ASCII is "enter" so scanf must also grab the "enter" key as a character.

Sure enough, looking at your scanf string, you are asking for a single character each time through your loop. Control characters are also considered characters, and will be picked up. For example, you can press "esc" then "enter" in the above loop and get:

enter val: ^[
got: 27
enter val: got: 10
查看更多
公子世无双
5楼-- · 2018-12-31 05:26
scanf(" %c", &fooBar);

Notice the space before the %c. This is important, because it matches all preceding whitespace.

查看更多
登录 后发表回答