I am trying to write my own printf function in c, but I faced with a problem, when I want to call my functions with this arguments :
ft_printf ("Characters: %c %c\n",'s','e');
instead of getting 's' 'e' , I got 's' 's'. It looks like it does not go through all arguments,
this is my function :
static int get_args(va_list args, char format)
{
if(format == 'c')
return(print_char(va_arg(args,int))); //here I called va_args to retrieve args
}
int ft_printf(const char *format, ...)
{
va_list args;
int i;
int len;
len = 0;
i = 0;
va_start(args,format);
while (format[i])
{
if (format[i] == '%')
{
len += get_args(args, format[i + 1]);
i++;
}
else
{
write(1,&format[i],1);
len++;
}
i++;
}
va_end(args);
return len;
}
int main()
{
printf ("Characters: %c %c \n",'s','e');
ft_printf ("Characters: %c %c\n",'s','e');
return 0;
}
After passing args
to get_args()
and calling va_arg
inside, the value of the original args
in ft_printf()
is indeterminate†, and you can only va_end
it.
However, if you pass it by reference (with a pointer), it properly updates args
in the original function:
static int get_args(va_list *args, char format)
{
if (format == 'c')
// here I called va_args to retrieve args
return print_char(va_arg(*args, int));
}
int ft_printf(const char *format, ...)
{
// ...
len += get_args(&args, format[i + 1]);
// ...
}
† On some platforms, va_list
is a type like an integer or pointer, so get_args
receives a copy and va_arg
can't update the original. On other platforms, it's an array type, so the function parameter becomes a pointer so it's automatically passed "by reference" and the original value is updated. You appear to be using a platform with the former type, where args
in ft_printf
isn't modified.