You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

scanf检测回车键致do-while循环重复执行,不用fgets如何修复?

解决scanf读取字符时捕获换行导致循环重复执行的问题

你的核心问题是输入缓冲区残留的换行符被scanf读取,导致玩家2的猜测循环意外执行两次。同时原代码中还有两个隐藏问题:Player1输入的单词包含fgets读取的换行符,导致掩码生成和最终的胜利判断逻辑失效,这也是你说"在%c前加空格会破坏校验逻辑"的根本原因。

以下是无需使用fgets替换scanf的解决步骤:

1. 清理Player1输入的换行符

fgets会把用户输入的回车键(\n)也存入数组,这会导致后续掩码长度错误、strcmp永远无法匹配(因为掩码里没有换行符)。在读取单词后立即去除换行符:

// 在fgets读取player1Word后添加
size_t wordLen = strlen(player1Word);
if (wordLen > 0 && player1Word[wordLen - 1] == '\n') {
    player1Word[wordLen - 1] = '\0';
}

2. 修复掩码生成逻辑

原代码中掩码循环的strlen(player1Word)-1是为了跳过换行符,现在换行符已被清理,直接用单词实际长度生成掩码,并手动添加字符串结束符避免乱码:

// 替换原掩码生成代码
int actualWordLen = strlen(player1Word);
for(int i = 0; i < actualWordLen; i++)
{
    player1WordMask[i] = '_';
}
player1WordMask[actualWordLen] = '\0'; // 添加字符串结束符

3. 清空scanf后的输入缓冲区

每次用scanf("%c", &player2Input)读取字符后,缓冲区会残留用户输入的换行符,下一次循环时scanf会直接读取这个换行符,导致循环重复执行。在读取字符后添加代码清空缓冲区:

// 在scanf读取player2Input后添加
scanf("%c",&player2Input);
// 清空缓冲区中剩余的所有字符(直到换行)
while ((getchar()) != '\n');

修改后的完整代码

#include <stdio.h>
#include <string.h>
#include <ctype.h>

#define WORDLIMIT 12
#define NUMBER_OF_GUESSES 7

char player1Word[WORDLIMIT];
char player1WordMask[WORDLIMIT];

char player2Input;
int player2GuessCount=7;

int specialCharFlag = 0;
int isWordAllowed = 0;
int guessCorrectly = 0;
int gameWon = 1;

int main(void)
{

    do //check if player 1 word is valid
    {
        // prompt and get the word
        printf("Player 1, enter a word of no more than %d letters:\n", WORDLIMIT-1);
        fgets(player1Word,WORDLIMIT,stdin);

        // 去除fgets读取的换行符
        size_t wordLen = strlen(player1Word);
        if (wordLen > 0 && player1Word[wordLen - 1] == '\n') {
            player1Word[wordLen - 1] = '\0';
        }

        // Player 1 enters a word with upper case letters, the program should change them to lower case.
        for(int i = 0; i<strlen(player1Word); i++)
        {
            player1Word[i] = tolower(player1Word[i]);
        }

        //special character flag
        specialCharFlag = 0;

        if (strlen(player1Word) >= WORDLIMIT)
        {
            printf("Enter a word of no more than %d letters:\n", WORDLIMIT-1);
            specialCharFlag = 1;
        }

        for (int i = 0; i < strlen(player1Word); i++)
        {
            // 判断是否为非法字符
            if (!isalpha(player1Word[i]))
            {
                printf("Sorry, the word must contain only English letters.\n");
                specialCharFlag = 1;
                break;
            }
        }

        isWordAllowed = (specialCharFlag == 0) ? 1 : 0;

    }
    while (isWordAllowed == 0);

    // 生成初始掩码
    int actualWordLen = strlen(player1Word);
    for(int i = 0; i < actualWordLen; i++)
    {
        player1WordMask[i] = '_';
    }
    player1WordMask[actualWordLen] = '\0';

    do
    {
        // 提示玩家2当前猜测进度
        printf("Player 2 has so far guessed: %s\n",player1WordMask);
        printf("Player 2, you have %d guesses remaining. Enter your next guess:\n",player2GuessCount);
        scanf("%c",&player2Input);
        // 清空输入缓冲区残留字符
        while ((getchar()) != '\n');

        player2Input = tolower(player2Input);

        guessCorrectly = 0;

        for (int i = 0; i < actualWordLen; i++)
        {
            if (player1Word[i] == player2Input)
            {
                player1WordMask[i] = player2Input;
                guessCorrectly = 1;
            }
        }

        if(guessCorrectly == 0)
        {
            player2GuessCount -= 1;
        }

        gameWon = strcmp(player1Word,player1WordMask);
        if(gameWon==0)
        {
            break;
        }

    }
    while(player2GuessCount!=0);

    if(gameWon == 0)
    {
        printf("Player 2 wins.\n");
    }
    else
    {
        printf("Player 1 wins. The word was: %s\n", player1Word);
    }

    return 0;
}

额外优化说明:

  • 用isalpha()简化非法字符判断,避免冗长的条件列表
  • 修正单词长度判断逻辑:数组大小为WORDLIMIT,实际允许的单词长度是WORDLIMIT-1(需要留位置给字符串结束符)
  • 补充了玩家2失败时的提示逻辑

内容的提问来源于stack exchange,提问作者user11270788

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.14 13:50:21