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

C语言if-else+strcmp实现落子功能时陷入错误循环问题排查

问题核心原因

代码出现随机列值、持续判定输入非法的核心原因是字符串缓冲区溢出,破坏了栈上相邻变量的内存数据。
C语言的字符串必须以\0作为结束标记,你一开始定义的char p1move[2]长度只有2字节,而"A1""B2"这类合法坐标包含2个可见字符,加上结束符总共需要3字节存储空间。用scanf("%s", p1move)读取输入时,函数会自动在输入内容末尾追加\0,多出来的1字节会直接越界写到栈上和p1move相邻的变量内存上——刚好column_move就挨着这个数组,所以写入的\0和后续越界读取的随机内存值会直接把column_move改成4196901这类无意义的大数;同时因为数组里没有正确的结束符,strcmp对比时会越界读取数组后方的随机内存内容,经常返回非0值,导致程序误判输入非法。你之前调整数组长度后问题依旧,大概率是只把长度设为2,依然没有为字符串结束符预留空间,溢出问题没有被解决。

其他隐藏逻辑bug
  • 每次do-while循环开始时没有重置invalid标记为0:只要用户第一次输入非法值把invalid设为1,后续哪怕输入正确坐标,invalid还是保持1,会一直判定输入非法。
  • C3坐标的下标赋值错误:原代码中C3的赋值是row_move = 1; column_move = 2;,和C2的下标完全一致,按照棋盘左上角为(0,0)的规则,C3正确对应下标应该是第0行第2列。
  • do-while循环的终止条件错误:原循环条件仅判断棋盘位置是否为空,没有把输入非法的场景纳入判断,出现非法输入时可能因为随机下标越界访问内存直接触发崩溃。
  • 原scanf没有加读取长度限制,用户输入过长内容时会直接触发缓冲区溢出。
修正后的可运行代码
#define PLAYER1 'X'
// 假设board为全局初始化的3*3棋盘数组,所有位置初始值为空格
char board[3][3];

void Player1Move()
{       
        // 缓冲区留足冗余长度,避免输入溢出
        char p1move[16];
        int row_move, column_move, invalid;
        printf("It's Player 1's turn!\n");
        printf("What's your move?\n");
        do
        {       
                // 每次循环开头重置标记和下标值,避免上次循环的残留值影响判断
                row_move = 0; 
                column_move = 0;
                invalid = 0;

                printf("Enter your move ");
                // 加读取长度限制,最多读取15个字符,预留1字节存字符串结束符
                scanf("%15s", p1move); 
                printf("YOUR MOVE IS %s\n", p1move);

                if(strcmp(p1move,"A1") == 0)
                {       
                        row_move = 2; 
                        column_move = 0; 
                } else if(strcmp(p1move, "A2") == 0)
                {       
                        row_move = 1; 
                        column_move = 0; 
                } else if(strcmp(p1move, "A3") == 0)
                {       
                        row_move = 0; 
                        column_move = 0; 
                } else if(strcmp(p1move, "B1") == 0)
                {       
                        row_move = 2; 
                        column_move = 1; 
                } else if(strcmp(p1move, "B2") == 0)
                {       
                        row_move = 1; 
                        column_move = 1; 
                } else if(strcmp(p1move, "B3") == 0)
                {       
                        row_move = 0; 
                        column_move = 1; 
                } else if(strcmp(p1move, "C1") == 0)
                {       
                        row_move = 2; 
                        column_move = 2; 
                } else if(strcmp(p1move, "C2") == 0)
                {       
                        row_move = 1; 
                        column_move = 2; 
                } else if(strcmp(p1move, "C3") == 0)
                {       
                        // 修正C3对应的行下标
                        row_move = 0; 
                        column_move = 2;
                } else
                {       
                        invalid = 1;
                }
                
                /* 校验输入合法性和棋盘位置是否空闲 */
                if(invalid == 1 || board[row_move][column_move] != ' ')
                {       
                        printf("That is not a valid space, please pick a new space\n");
                } else
                {       
                        board[row_move][column_move] = PLAYER1;
                        break;
                }
        // 修正循环条件:只要输入非法、或者选中位置已被占用,就持续要求用户重新输入
        } while(invalid == 1 || board[row_move][column_move] != ' ');
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 16:31:35