自定义printf实现中%pd格式宽度解析异常问题求助
问题根因
这个异常完全是宽度识别分支的跳转逻辑写错了,三个连锁问题直接导致了输出偏差:
- 流程错位直接跳过格式匹配
处理%5d时,指针刚越过%指向数字5,就进入了数字判断分支。这个分支执行完逻辑直接用continue跳回最外层主循环,此时指针只向后挪了1位,刚好落在d的位置。
主循环的第一行规则是:只要当前字符不是%,就直接原样输出。因此d会被当成普通字符打印出来,根本走不到后面switch匹配格式符的代码块——这就是你看到末尾单独输出d的直接原因。 - 宽度计算逻辑完全错误
数字分支里的计算逻辑是precision = precision*10 + atoi(format),且每次只把指针挪1位:
如果遇到多位数宽度比如%12d,第一次走到1的位置时,atoi会直接解析出后续整串数字12,算出precision=12,指针挪到2的位置触发跳转;下次循环又判断2是数字,重新解析出数字2,算出precision=12*10+2=122,宽度值完全算错。 - 状态没有重置
存宽度的precision变量是函数内的局部变量,每次处理新的格式说明符时根本没有清零,前一个格式符的宽度值会一直带入后续所有格式的计算里,越跑越错。
修复思路
- 刚越过
%符号时,先把宽度变量重置为0 - 遇到连续数字时,用循环逐个读字符算宽度,每读一个数字就把指针向后挪1位,直到碰到非数字字符为止
- 读完宽度数字后不要
continue跳回主循环,直接顺着指针当前位置做格式符匹配 - 处理带符号整数的宽度时,不要漏算负号占的1个字符位置,不然补空格的数量会算错
核心代码修改参考
把原来的数字识别分支替换成下面的逻辑:
format++; // 已经越过%符号,先重置宽度值 int width = 0; // 循环读完所有连续的宽度数字 while(isdigit(*format)) { width = width * 10 + (*format - '0'); format++; } // 读完数字直接做格式符匹配,不要跳转 switch(*format) { // 原有case逻辑保持不变,补空格时用width值替代原来的precision }
内容的提问来源于stack exchange,提问作者Andrei0408
相关产品推荐
相关产品推荐

