自定义C语言printf函数多参数输出异常问题排查求助
自定义C语言_printf函数参数异常排查
实现自定义C语言_printf函数时,遇到传入4个及以上参数时输出结果不符合预期的问题,以下是相关代码、测试用例及输出情况:
代码实现
#include <stdio.h> #include <stdarg.h> #include <unistd.h> #include <string.h> #include <stdlib.h> int _printf(const char *format, ...); int main() { _printf("%c%cth %s%s a%cg%s: Y%sou %s no%ching%s Snow.%c", 'W', 'i', "some ", "more", 'r', "s", "", "know", 't', ", Jon", '\n'); } /** * _printf - Custom printf function * @format: A string containing the characters to print * Return: the count of the printed characters */ int _printf(const char *format, ...) { va_list args; int count = 0; int i, j, length = 0; char c, *p, *ptr; va_start(args, format); if (format == NULL) return (-1); for (i = 0; format[i] != '\0'; i++) { if (format[i] == '%') { i++; if (format[i] == 'c') { c = va_arg(args, int); count += write(1, &c, 1); } if (format[i] == 's') { ptr = va_arg(args, char*); if (ptr == NULL) count += write(1, "(null)", 6); else { while (*ptr != '\0') { length++; ptr++; } p = malloc((length + 1) * sizeof(char)); for (j = 0; j < (length + 1); j++) p[length - j] = *(ptr - j); count += write(1, p, length); free(p); } } if (format[i] == '%') count += write(1, &format[i], 1); } else count += write(1, &format[i], 1); } va_end(args); return (count); }
测试用例
_printf("%c%cth %s%s a%cg%s: Y%sou %s no%ching%s Snow.%c", 'W', 'i', "some ", "more", 'r', "s", "", "know", 't', ", Jon", '\n');
预期输出
With some more args: You know nothing, Jon Snow.
实际错误输出
With some more argonknows: Y Jonknowou .%c, Jonknow nothinging%s Snow.%c, Jon Snow.
问题排查与修复
length变量未重置:每次处理%s时,length没有初始化,会累加之前所有字符串的长度,导致后续字符串长度计算完全错误。需要在进入%s分支时立即重置length为0。字符串复制逻辑错误:计算完字符串长度后,
ptr已经指向字符串末尾,后续的反向复制逻辑会把字符串反转,并且没有正确复制原字符串。实际上不需要额外malloc内存,直接使用原字符串指针配合长度调用write即可,既高效又避免错误。多分支判断冗余:使用
if连续判断会导致匹配到c后仍会检查s和%,改用else if可以减少不必要的判断,提升效率。
修复后的代码
#include <stdio.h> #include <stdarg.h> #include <unistd.h> #include <string.h> #include <stdlib.h> int _printf(const char *format, ...); int main() { _printf("%c%cth %s%s a%cg%s: Y%sou %s no%ching%s Snow.%c", 'W', 'i', "some ", "more", 'r', "s", "", "know", 't', ", Jon", '\n'); } /** * _printf - Custom printf function * @format: A string containing the characters to print * Return: the count of the printed characters */ int _printf(const char *format, ...) { va_list args; int count = 0; int i, length; char c, *ptr; va_start(args, format); if (format == NULL) return (-1); for (i = 0; format[i] != '\0'; i++) { if (format[i] == '%') { i++; if (format[i] == 'c') { c = va_arg(args, int); count += write(1, &c, 1); } else if (format[i] == 's') { ptr = va_arg(args, char*); if (ptr == NULL) { count += write(1, "(null)", 6); } else { length = 0; // 计算字符串长度 while (ptr[length] != '\0') { length++; } count += write(1, ptr, length); } } else if (format[i] == '%') { count += write(1, &format[i], 1); } } else count += write(1, &format[i], 1); } va_end(args); return (count); }
修复后运行测试用例,即可得到符合预期的输出。
内容的提问来源于stack exchange,提问作者Hamdi Larbi
相关产品推荐
相关产品推荐

