十进制转2-16进制的encode函数无输出问题求助
问题排查与修复方案
你的代码存在三个核心问题,导致printf无法正确输出转换结果:
1. 数字未转换为对应ASCII字符
当进制b≤10时,d%b得到的是0-9的数值(比如5),你直接将数值赋值给char变量,对应的是ASCII码值5(不可见控制字符),而非字符'5'(ASCII码值53)。必须给数值加上'0'才能转换为可显示的数字字符。
2. 字符串起始位置错误,前置空字符导致输出截断
你用calloc初始化了全为'\0'的数组,然后从数组末尾往前存字符,但printf输出字符串时会从指针起始位置开始,遇到第一个'\0'就停止。数组前半段都是'\0',所以直接输出为空。需要返回有效字符的起始地址,而非整个数组的首地址。
3. 未处理输入d=0的特殊情况
当输入d=0时,while(d>0)循环不会执行,返回的数组全是'\0',无法输出预期的"0"。
修复后的完整代码
#include <stdio.h> #include <stdlib.h> #include <string.h> #define SIZE 20 char *encode(unsigned int d, unsigned char b){ if(b<2||b>16) return NULL; char *resto = calloc(SIZE, sizeof(char)); // 处理d=0的情况 if(d == 0){ resto[SIZE-1] = '0'; return resto + SIZE - 1; } int i=1; while(d>0){ int rimanenza = d%b; d = d/b; char c; if(rimanenza < 10){ c = rimanenza + '0'; // 转换为数字字符 } else { c = rimanenza - 10 + 'A'; // 转换为A-F大写字母 } resto[SIZE - i] = c; i++; } // 返回有效字符的起始地址 return resto + SIZE - i + 1; } int main (){ unsigned int d = 126; unsigned char b = 3; char *encoded = encode(d,b); printf("%u in base %u = %s\n",d,b,encoded); // 释放原始分配的内存(需计算回数组首地址) free(encoded - (SIZE - strlen(encoded))); return 0; }
关键修复点说明
- 字符转换:通过
rimanenza + '0'将数值转为对应数字字符,10及以上数值通过rimanenza -10 + 'A'转为大写字母。 - 调整返回地址:计算有效字符的起始位置,让
printf直接从第一个有效字符开始输出。 - 特殊值处理:单独判断
d=0的情况,确保输出正确。 - 内存释放:由于返回的是数组中间的指针,释放时需计算回原始分配的首地址,避免内存泄漏。
内容的提问来源于stack exchange,提问作者Filippo Piombino
相关产品推荐
相关产品推荐

