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

为何C语言程序中scanf函数会意外一次性读取多个输入?

解决剪刀石头布程序中scanf读取换行符导致的流程混乱问题

你的程序出现流程混乱,核心是三个问题:

  1. scanf读取换行符:输入字符后按回车,回车的\n会留在输入缓冲区,下一次scanf("%c")会直接读取这个换行符,而非等待用户输入,触发错误提示。
  2. 条件判断逻辑错误:原代码输入验证用了||(逻辑或),比如inp1 != 'p' || inp1!='r'|| inp1!='s',这个条件永远为真——一个字符不可能同时是p、r、s,哪怕输入正确字符,也会触发错误提示。
  3. 循环变量未重置:LOOP2和LOOP3在第一次循环后被设为0,后续外层循环不会再进入输入验证的内层循环,直接跳过输入步骤。

修复后的完整代码

#include <stdio.h>

int main(int argc, char* argv[])
{
    char inp1, inp2, inp3;
    int LOOP1 = 1;
    
    while (LOOP1 == 1)
    {
        int LOOP2 = 1, LOOP3 = 1; // 每次外层循环重置循环变量
        printf("Player-1 it is your turn!\nPlease enter your choice (p)aper, (r)ock, or (s)cissors: ");
        
        while (LOOP2 == 1)
        {
            scanf(" %c", &inp1); // 空格跳过空白字符(包括换行)
            // 修正逻辑:用&&判断输入是否不在合法范围内
            if (inp1 != 'p' && inp1 != 'r' && inp1 != 's')
            {
                printf("I'm sorry, I do not understand.\nPlease enter your choice (p)aper, (r)ock, or (s)cissors: ");
            }
            else
            {
                LOOP2 = 0;
            }
        }
        
        printf("Player-2 it is your turn!\nPlease enter your choice (p)aper, (r)ock, or (s)cissors: ");
        
        while (LOOP3 == 1)
        {
            scanf(" %c", &inp2); // 同样加空格跳过空白字符
            if (inp2 != 'p' && inp2 != 'r' && inp2 != 's')
            {
                printf("I'm sorry, I do not understand.\nPlease enter your choice (p)aper, (r)ock, or (s)cissors: ");
            }
            else
            {
                LOOP3 = 0;
            }
        }
        
        if (inp2 == 'p')
        {
            if (inp1 == 'p')
                printf("No one wins.\n");
            if (inp1 == 'r')
                printf("Player-2 wins! Paper covers rock.\n");
            if (inp1 == 's')
                printf("Player-1 wins! Scissors cuts paper.\n");
        }
        if (inp2 == 'r')
        {
            if (inp1 == 'p')
                printf("Player-1 wins! Paper covers rock.\n");
            if (inp1 == 'r')
                printf("No one wins.\n");
            if (inp1 == 's')
                printf("Player-2 wins! Rock breaks scissors.\n");
        }
        if (inp2 == 's')
        {
            if (inp1 == 'p')
                printf("Player-2 wins! Scissors cuts paper.\n");
            if (inp1 == 'r')
                printf("Player-1 wins! Rock breaks scissors.\n");
            if (inp1 == 's')
                printf("No one wins.\n");
        }
        
        printf("Do you wish to continue? (y/n): ");
        scanf(" %c", &inp3); // 同样加空格处理换行
        if (inp3 == 'n')
            LOOP1 = 0;
    }

    return 0;
}

关键修改点说明

  • 处理换行符:在%c前加空格" %c",scanf会自动跳过所有空白字符(换行、空格、制表符),只读取有效输入字符,避免缓冲区残留的换行符干扰。
  • 修正条件判断:把输入验证的逻辑或||改成逻辑与&&,只有当输入既不是p、也不是r、也不是s时,才输出错误提示,逻辑正确。
  • 重置循环变量:把LOOP2和LOOP3的声明移到外层循环内部,每次外层循环开始时都会重新初始化为1,确保每次输入都能进入验证循环。
  • 统一换行格式:将原代码中不规范的换行改为标准的\n,保证输出格式清晰。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 11:55:26