如何实现C语言字符串数组的循环遍历以计算跨边界月份区间费用
原代码核心问题定位
- 跨边界循环逻辑失效:当
end < start(跨年场景)时,原循环条件i < start - end永远不成立,循环一次都不会执行,完全无法统计区间内的月份数。 total未初始化:栈上的局部浮点数默认是随机垃圾值,即使同年内场景的计算结果也会出错。- 字符数组长度不足:数组中存储的
"April"包含5个字符,加上字符串结束符\0共需要6字节,当前定义的char start_m[5]/char end_m[5]会导致输入"April"时缓冲区溢出,破坏内存数据。 - 缺少输入校验:如果用户输入的月份拼写错误,
start/end不会被赋值,是未初始化的垃圾值,会引发未知逻辑错误。
统一逻辑的实现方案
不需要分场景写两套循环,可以通过调整结束月份的索引,把跨年场景映射为“同年内”的计算逻辑,彻底避免边界判断错误:
- 初始化所有用到的变量(
total、start、end)为默认值,避免垃圾值影响计算。 - 扩展输入字符数组的长度到6,容纳"April"加字符串结束符,同时初始化数组为空,避免残留垃圾字符干扰字符串比较。
- 找到起始、结束月份的索引后,判断如果
end < start,就把end加上12,相当于把跨年的结束月份映射到下一年的索引(比如次年1月索引为12,次年7月索引为18)。 - 后续循环逻辑和同年内完全统一,不需要额外分支判断。
修正后的可运行代码
#include <stdio.h> #include <string.h> int main() { char *months[] = {"Jan", "Feb", "Mar", "April", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"}; // 扩展数组长度到6,同时初始化清空 char start_m[6] = {0}; char end_m[6] = {0}; float bill = 0.0f, rate = 0.0f; // 初始化total为0,避免垃圾值干扰 float total = 0.0f; scanf("%s %s %f %f", start_m, end_m, &bill, &rate); int i = 0, start = -1, end = -1; for(i = 0; i < 12; i++){ if(strcmp(months[i], start_m) == 0){ start = i; } if(strcmp(months[i], end_m) == 0){ end = i; } } // 校验输入的月份是否合法 if (start == -1 || end == -1) { printf("Invalid month input\n"); return 1; } // 统一调整end索引,跨年场景加12映射为下一年的索引 if(end < start) { end += 12; } // 统一循环逻辑,无需分场景判断 for(i = start; i < end; i++){ total += bill * rate; } total += bill; printf("%.2f", total); return 0; }
逻辑验证示例
- 同年内场景:起始Jan(索引0)、结束Jul(索引6),不触发end调整,循环i从0到5共6次,加6次
bill*rate后再加bill,对应7个月的总费用,符合预期。 - 跨年场景1:起始Feb(索引1)、结束次年Jan(索引0),
end调整为0+12=12,循环i从1到11共11次,加11次bill*rate后再加bill,对应12个月的总费用,结果正确。 - 跨年场景2:起始Dec(索引11)、结束Jul(索引6),
end调整为6+12=18,循环i从11到17共7次,加7次bill*rate后再加bill,对应8个月的总费用,符合预期。
内容的提问来源于stack exchange,提问作者Newbieee
相关产品推荐
相关产品推荐

