C语言中移除查询字符串首字符时for循环异常问题排查
分析你的C代码循环异常问题
嘿,我一眼就瞅出你这段代码里for循环的问题啦,这几个点直接导致了异常:
问题根源拆解
- 数组越界访问:你定义的
nome数组长度是strlen(args)-1,但循环里i从strlen(args)开始(也就是原字符串终止符\0的位置),这时候nome[i]已经超出了数组的合法下标范围,直接触发未定义行为,程序大概率会崩或者输出乱码。 - 复制逻辑完全颠倒:你想去掉首字符
_,应该把args[1]到args[strlen(args)-1]的内容复制到nome[0]到nome[strlen(args)-2],但你的循环是从后往前赋值,还把原字符串的终止符放到了越界位置,完全没拿到正确的内容。 - 缺少字符串终止符:即使复制逻辑对了,你也没给
nome手动添加\0,C语言字符串必须以这个字符结尾,否则后续函数(比如lerficheiro)处理时会把内存里的垃圾值当成字符串的一部分。
修正后的代码方案
我给你调整了两种写法,你可以选顺手的用:
写法1:手动循环复制(更直观)
ESTADO ler_estado(char *args) { // 先处理空输入,顺便加个NULL判断更安全 if (args == NULL || strlen(args) == 0) { return inicializar(); } if (args[0] == '_') { // 计算去掉首字符后的有效字符长度 size_t nome_len = strlen(args) - 1; // 定义数组时预留终止符的位置,长度为有效字符数+1 char nome[nome_len + 1]; // 从args的第2个字符(下标1)开始,逐个复制到nome for (size_t i = 0; i < nome_len; i++) { nome[i] = args[i + 1]; } // 手动添加字符串终止符 nome[nome_len] = '\0'; return lerficheiro(nome); } return str2estado(args); }
写法2:用strcpy简化代码(更简洁)
如果不需要手动控制复制过程,直接用C标准库的strcpy更省心,args+1就代表跳过首字符的字符串起始地址:
ESTADO ler_estado(char *args) { if (args == NULL || strlen(args) == 0) { return inicializar(); } if (args[0] == '_') { size_t nome_len = strlen(args) - 1; char nome[nome_len + 1]; // 直接复制跳过首字符的部分 strcpy(nome, args + 1); return lerficheiro(nome); } return str2estado(args); }
额外小提醒
原代码里的数组定义char nome[strlen(args)-1];本身就有问题,因为字符串需要\0结尾,所以数组长度必须是有效字符数+1,不然存不下终止符,这也是潜在的bug哦~
内容的提问来源于stack exchange,提问作者PedroCastro
相关产品推荐
相关产品推荐

