C语言象棋程序Bug:每次走棋后棋盘左上角元素变为'-'
问题根源:缓冲区溢出
你定义的char move[4];只能存储3个有效字符加字符串结束符'\0',但输入的走棋指令是4个字符(比如e2e4),写入时会超出数组边界,触发缓冲区溢出——栈上紧邻move的board数组首元素被意外修改,所以每次走棋后左上角棋子都会变成'-'。
C语言中字符串必须以'\0'结尾,4个字符的输入至少需要5字节空间,move[4]的空间不足,溢出的字节刚好覆盖了board[0][0]的内存区域,把它改成了NONE类型。
修复步骤
- 扩大输入缓冲区:把
char move[4];改成char move[5];,确保能装下4个字符加结束符。 - 限制输入长度:用
scanf("%4s", move);代替原来的scanf("%s", move);,强制最多读4个字符,避免输入过长再次溢出。 - 调整错误处理逻辑:原来遇到非法输入直接
return 1退出程序太粗暴,改成continue让用户重新输入更合理。
修改后的核心代码片段
// 替换原输入相关代码 char move[5]; printf("Move Number: %.f\n",ceil(moveNum)); printf("Enter move: "); scanf("%4s", move); // 先做坐标合法性检查,再获取棋子指针 int originalFile = move[0] - 'a'; int originalRank = 8 - (move[1] - '0'); int destFile = move[2] - 'a'; int destRank = 8 - (move[3] - '0'); if (originalRank < 0 || originalRank > 7 || originalFile < 0 || originalFile > 7 || destRank < 0 || destRank > 7 || destFile < 0 || destFile > 7) { printf("Invalid move: outside board\n"); continue; // 让用户重新输入,而非直接退出 } struct Piece* originalPiece = &board[originalRank][originalFile]; struct Piece* destPiece = &board[destRank][destFile];
额外优化建议
- 增加输入长度校验:如果
strlen(move) !=4,提示用户输入4字符格式的指令(比如"请输入正确格式,如e2e4")。 - 空位置的
NONE类型棋子,颜色可以随便设置(反正piece_to_char只判断type),统一设为BLACK或WHITE都不影响功能。
内容的提问来源于stack exchange,提问作者hungryjumper586
相关产品推荐
相关产品推荐

