Junius L
Junius L

Reputation: 16132

va_arg with wide char in c, how to handle %S

I'm trying to implement my own printf, I have an issue handling wide char %S.

void    my_printf(char *format, ...)
{
    char            *traverse;
    va_list         arg;

    va_start(arg, format);
    traverse = format;
    while (*traverse)
    {
        if (*traverse == '%')
        {
            *traverse++;
            if (*traverse == 'S')
                printf("%S\n", va_arg(arg, wchar_t));
            *traverse++;
        }
        else
            putchar(*traverse++);
    }
    va_end(arg);
}

warning: format specifies type 'wchar_t *' (aka 'int *') but the argument has type 'wchar_t' (aka 'int') [-Wformat] printf("%S\n", va_arg(arg, wchar_t));

when I use following code printf works fine.

printf("%S\n", L"Some String");

Upvotes: 1

Views: 2128

Answers (1)

2501
2501

Reputation: 25752

You're passing a pointer and retrieving an integer. The types of L"Some String" and va_arg(arg, wchar_t), do not match.

Retrieve a pointer instead:

 va_arg(arg, wchar_t*)

The line *traverse++; is not correct, the dereference is redundant. It should be simply: traverse++;


On a side note, your code doesn't do any input checking and a malicious string will cause undefined behavior. This will happen if the character '%' is the last character, the iterator traverse will point to one beyond the last element in the array and the check while (*traverse) will dereference it.

Upvotes: 3

Related Questions