C语言自定义进制转换函数转十六进制时首位结果错误
为什么转十六进制时首位数字处理错误
调用自定义函数ft_transformers传入参数nbr=894867、目标进制i=16时,实际输出为=A793,该数值转十六进制的正确结果为DA793,首位字符转换异常,原实现代码如下:
void ft_transformers(int nbr, int i) { char num[100]; int t; int temp; int j; temp = 0; t = 0; while (nbr != 0) { temp = nbr % i; if (num[t] < 10) { num[t] = temp + 48; } else { num[t] = temp + 55; } nbr /= i; t++; } j = t; while (j >= 0) { ft_putchar(num[j]); j--; } }
错误原因
代码存在两个直接导致输出异常的逻辑bug:
- 字符转换判断对象错误:判断余数对应数字/字母的分支条件,错误使用了未初始化的数组元素
num[t]做判断,而非实际计算得到的余数temp。栈上未初始化的数组内存存储的是随机垃圾值,当余数≥10需要转换为A-F格式时,只要num[t]的随机值小于10,就会错误走数字转换分支,计算出错误的ASCII值。比如最后一步计算得到余数13(对应十六进制字符D),此时若num[t]随机值小于10,会执行13+48=61,刚好对应ASCII字符=,就是输出里的首位异常字符。 - 逆序输出索引越界:逐位取余写入数组结束后,变量
t指向的是下一个待写入的空位置,比最后一个有效字符的索引大1。代码直接将j初始化为t,首先会读取到未写入的数组垃圾值,其次循环条件j >=0会最终访问到num[-1]的越界内存,输出不可预期的字符。
修复方案
针对两个bug做对应修正即可,同时补充输入为0时的边界处理,避免传入0时无输出:
void ft_transformers(int nbr, int i) { char num[100]; int t; int temp; int j; temp = 0; t = 0; // 处理0值边界 if (nbr == 0) { ft_putchar('0'); return; } while (nbr != 0) { temp = nbr % i; // 修正判断对象为当前余数 if (temp < 10) { num[t] = temp + 48; } else { num[t] = temp + 55; } nbr /= i; t++; } // 修正起始索引为最后一个有效字符位置 j = t - 1; while (j >= 0) { ft_putchar(num[j]); j--; } }
修复后传入894867、进制16时,会正确输出DA793。
内容的提问来源于stack exchange,提问作者marko MK ツ
相关产品推荐
相关产品推荐

