日期转换程序异常Bug求助:输入08/09月份时程序失效
问题分析与解决方案:MM/DD/YYYY转Month DD, YYYY时08/09月份失效
问题根源
你在convert_month函数中使用strtol(m, &rem, 0)转换月份字符串时,第三个参数传0会触发C语言的自动进制识别规则:
- 以
0开头的字符串会被默认解析为八进制数 - 八进制的有效数字范围是0-7,因此
"08"和"09"会被判定为无效输入,strtol返回0,同时未转换的字符会留在rem指向的位置
当转换结果month=0时,months[month-1]等价于访问months[-1],这属于数组越界操作,直接导致程序行为异常。
解决方案
方法1:强制十进制解析(最简修复)
修改convert_month函数,将strtol的第三个参数明确设为10,强制按十进制解析字符串:
int convert_month( char *m ) { char *rem; // 指定十进制解析,忽略前导0的影响 return strtol( m, &rem, 10); }
这样"08"会被正确转换为整数8,"09"转换为9,对应到months[7](August)和months[8](September),输出正常。
方法2:添加输入合法性检查(增强健壮性)
可以在转换后验证结果的有效性,避免非法月份(如"13"、"0a")导致的错误:
int convert_month( char *m ) { char *rem; long month_val = strtol( m, &rem, 10); // 检查是否存在未转换的非法字符,且月份值在1-12范围内 if (*rem != '\0' || month_val < 1 || month_val > 12) { fprintf(stderr, "错误:无效的月份格式\n"); exit(EXIT_FAILURE); } return (int)month_val; }
方法3:直接字符串匹配(替代数值转换)
如果不想依赖数值转换,也可以直接将输入的月份字符串与预设的MM格式列表匹配:
int convert_month( char *m ) { char *month_strs[12] = {"01","02","03","04","05","06","07","08","09","10","11","12"}; for (int i = 0; i < 12; i++) { if (strcmp(m, month_strs[i]) == 0) { return i + 1; // 返回1-12的月份编号 } } fprintf(stderr, "错误:无效的月份\n"); exit(EXIT_FAILURE); }
额外优化提示
read_date函数中,虽然orig_date的大小(11)刚好容纳MM/DD/YYYY格式的字符串(长度为10),但可以在输入时加入格式检查(只允许数字和/),避免非法字符干扰后续的strtok拆分。strtok会直接修改原字符串orig_date,如果需要保留原始输入的日期内容,建议在拆分时将每个元素复制到新的内存空间中。
内容的提问来源于stack exchange,提问作者Talete
相关产品推荐
相关产品推荐

