自定义C语言printf函数输出负数时尾部出现垃圾字符问题求助
自定义printf的负数输出问题排查与解决
我正在用C语言实现自定义版本的printf函数,其余功能均正常,但输出负数时,目标数字后会附加垃圾字符。
相关代码
const char g_chars[] = "0123456789abcdef"; void printf_unsigned(unsigned int num, int base) { char string[32]; int pos = 0; do { int rem = num % base; num /= base; string[pos++] = g_chars[rem]; } while (num > 0); while (--pos >= 0) { PrintChar(string[pos]); } } void printf_signed(int num, int base) { if (num < 0) { PrintChar('-'); printf_unsigned(num * -1, base); } printf_unsigned(num, base); }
其中printf_unsigned函数可将二进制数转为ASCII并逐字符打印,功能正常;printf_signed函数判断数字是否为负,负数则先打印'-'再调用printf_unsigned传入其绝对值,否则直接调用printf_unsigned。
调用示例
printf_signed(-3, 10); printf_signed(-10, 10); printf_signed(-15, 10);
实际输出
-34294967293 -104294967286 -154294967281
问题原因
- 重复执行打印逻辑:
printf_signed中,当num < 0时,执行完负数分支的打印后,没有终止函数,会继续执行后面的printf_unsigned(num, base)。负数被转换为unsigned int时会变成一个很大的正数(比如-3转成unsigned int是4294967293),这就是末尾附加的"垃圾字符"来源。 - 负数取反溢出风险:对于
int类型的最小值(如32位int的INT_MIN = -2147483648),执行num * -1会触发溢出,属于C语言中的未定义行为。
修复代码
#include <limits.h> const char g_chars[] = "0123456789abcdef"; void printf_unsigned(unsigned int num, int base) { char string[32]; int pos = 0; do { int rem = num % base; num /= base; string[pos++] = g_chars[rem]; } while (num > 0); while (--pos >= 0) { PrintChar(string[pos]); } } void printf_signed(int num, int base) { if (num < 0) { PrintChar('-'); // 转unsigned处理,避免INT_MIN取反溢出 printf_unsigned((unsigned int)(-num), base); // 终止函数,防止重复打印 return; } printf_unsigned((unsigned int)num, base); }
修复说明
- 添加
return语句:在负数分支处理完成后立即返回,彻底避免后续的重复打印操作。 - 安全处理绝对值:将负数转为
unsigned int类型计算,利用无符号类型的定义转换规则,既避免了溢出问题,又能正确获取对应绝对值的无符号表示。
内容的提问来源于stack exchange,提问作者neta cohen
相关产品推荐
相关产品推荐

