You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

自定义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.


问题排查与修复

  1. length变量未重置:每次处理%s时,length没有初始化,会累加之前所有字符串的长度,导致后续字符串长度计算完全错误。需要在进入%s分支时立即重置length为0。

  2. 字符串复制逻辑错误:计算完字符串长度后,ptr已经指向字符串末尾,后续的反向复制逻辑会把字符串反转,并且没有正确复制原字符串。实际上不需要额外malloc内存,直接使用原字符串指针配合长度调用write即可,既高效又避免错误。

  3. 多分支判断冗余:使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.01 16:37:34