C语言实现最多10次录入可提前终止的数组循环问题
核心问题排查
代码存在以下逻辑错误,导致无法实现预期功能:
- do-while循环判断条件写法错误:
while (minfo == 'y' || 'Y')属于恒真表达式,字符常量'Y'本身是非0值,逻辑或运算只要一侧为真整体就为真,循环永远不会靠while条件终止。 - 计数逻辑完全失效:在循环内部定义
int ii = 0,每次进入循环ii都会被重置为0,永远不可能触发大于9的上限判断;同时作为数组下标的变量i从未自增,所有录入的姓名都会覆盖name[0]的存储空间。 - 最终输出逻辑错误:遍历了全部10个数组槽位,未录入的槽位是未初始化的垃圾值,会输出乱码。
- 存在缓冲区溢出风险:
scanf("%s", buffer)没有限制输入长度,一旦输入的姓名长度超过数组容纳上限会直接越界写入内存。 - 宏定义命名无意义,
a/b/luff这类标识符很容易在写逻辑时搞错对应含义。
修正后可运行代码
#include <stdio.h> #include <string.h> #define MAX_PLAYER 10 #define NAME_LEN 32 #define BUF_SIZE 1024 int main() { char name[MAX_PLAYER][NAME_LEN]; char buffer[BUF_SIZE]; int count = 0; char choice; do { // 达到最大录入数量直接终止 if (count >= MAX_PLAYER) { printf("已达到最多10名玩家的录入上限\n"); break; } printf("请输入玩家姓名:\n"); // 限制输入长度,预留1字节给字符串结束符\0,防止溢出 scanf("%31s", buffer); strcpy(name[count], buffer); count++; printf("\n是否继续添加更多玩家?(Y/N):\n"); scanf(" %c", &choice); // 格式串前的空格用于跳过之前残留的换行、空白符 if (choice == 'n' || choice == 'N') { break; } } while (choice == 'y' || choice == 'Y'); // 仅遍历实际录入的有效数据 printf("\n已录入的玩家列表:\n"); for (int i = 0; i < count; i++) { printf("玩家%d:%s\n", i+1, name[i]); } return 0; }
实现逻辑说明
- 用
count变量统一记录实际录入的玩家数量,同时作为数组下标使用,每成功录入1个姓名就自增1,既不会出现下标覆盖的问题,也能直接作为最终输出的循环终止条件。 - 进入循环首先判断是否达到10人的录入上限,达到就直接提示并退出,不需要再询问用户是否继续。
- 读姓名时加了长度限制
%31s,最多读31个字符,预留1字节存字符串结束符,避免内存越界。 - 循环判断条件修正为同时校验选择变量是否等于'y'或'Y',不会出现恒真的问题。
- 最终输出只遍历0到count-1的数组元素,不会输出未初始化的垃圾内容。
内容的提问来源于stack exchange,提问作者anti443
相关产品推荐
相关产品推荐

