C语言如何定位字符数组中的数字子串并转换为整型数值
问题解决:C语言从混合分号分隔的字符串中提取数字并转整型
问题根因
- 数组越界访问:原代码遍历初始下标为
sizeof(busy),超出了字符数组的合法下标范围(C语言数组下标从0开始,长度为30的数组合法下标为0~29),导致定位逻辑容易出现异常。 - 数字片段无字符串结束符:标准库转换函数
atoi/strtol要求输入为\0结尾的C字符串,你提取的数字片段后直接跟分号等其他字符,不满足转换要求,因此转换失败。
调整后的完整代码
#include <stdio.h> #include <stdlib.h> #include <string.h> int main() { char busy[30] = "this is; it was; 163; 234;;"; int tag = 0; int location = 0; // 修正遍历起始下标,从最后一个有效字符开始,避免越界 for (int i = strlen(busy) - 1; i >= 0; i--) { if (busy[i] == ';') { tag++; } if (tag == 4) { location = i; break; } } location += 1; int loca_saved = 0; int loca_finish = 0; int tag1 = 0; while (busy[location] != ';') { // 优化空格跳过逻辑,跳过数字前所有前置空格 if (busy[location] == ' ' && tag1 == 0) { location++; } else { if (tag1 == 0) { tag1 = 1; loca_saved = location; // 记录数字第一个字符位置 } if (busy[location + 1] == ';') { loca_finish = location; // 记录数字最后一个字符位置 } putchar(busy[location]); location++; } } printf("\n"); // 转换方案1:临时修改原字符串加结束符,逻辑简单适合确定数字合法的场景 char old_char = busy[loca_finish + 1]; busy[loca_finish + 1] = '\0'; int num = atoi(busy + loca_saved); busy[loca_finish + 1] = old_char; // 可选:恢复原字符串内容 printf("atoi转换得到的整型值为:%d\n", num); // 转换方案2:用strtol无需修改原字符串,支持合法性校验,容错性更高 char *endptr; long num2 = strtol(busy + loca_saved, &endptr, 10); if (endptr == busy + loca_finish + 1) { printf("strtol转换得到的整型值为:%ld\n", num2); } else { printf("转换失败,目标片段包含非数字字符\n"); } return 0; }
核心修改说明
- 遍历起始位置调整为
strlen(busy)-1,既避免数组越界,也跳过了数组末尾未使用的0值区域,提升遍历效率。 - 优化了数字前置空格的跳过逻辑,避免边界判断错误。
- 两种转换方案可按需选择:
- 临时加结束符方案逻辑简单,适合确定目标片段全为数字的场景
strtol方案不需要修改原字符串,还可以通过endptr验证转换有效性,适合输入不确定的场景
内容的提问来源于stack exchange,提问作者LePiff
相关产品推荐
相关产品推荐

