3

I have a problem. I try to make custom printf() but when I compile this code, the output doesn't seem to come as predicted.

#include <stdio.h>
#include <stdarg.h>
void print(char *, ...);

int main()
{
    char str[12]="World";
    char c='A';
    int i=100;
    print("Hello %s %c", str, c);
}

void print(char *c, ...)
{
    char *s;
    va_list lst;
    va_start(lst, c);
    while(*c!='\0')
    {
        if(*c!='%')
        {
            putchar(*c);
            c++;
            continue;
        }
        c++;
        switch(*c)
        {
        case 's': fputs(va_arg(lst, char *), stdout); break;
        case 'c': putchar(va_arg(lst, int)); break;
        }
    }    
}

Output which seem to come:Hello World Output: Hello Worlds Ac I can't figure out why 's, c' appears.

1

2 Answers 2

5

You aren't incrementing the pointer c after your switch case, so the while loop runs again for the characters you are using as options.

Just add c++ after your switch case, like so:

void print(char *c, ...)
{
    char *s;
    va_list lst;
    va_start(lst, c);
    while(*c!='\0')
    {
        if(*c!='%')
        {
            putchar(*c);
            c++;
            continue;
        }
        c++;
        switch(*c)
        {
            case 's': fputs(va_arg(lst, char *), stdout); break;
            case 'c': putchar(va_arg(lst, int)); break;
        }
        c++;
    }
}

After making this change, I would recommend finding some way of also handling the case where the % appears at the end of the string, to avoid running into a buffer overflow. For example, before the switch, maybe check if we have reached a null terminator, and if so, break out of the loop.

void print(char *c, ...)
{
    char *s;
    va_list lst;
    va_start(lst, c);
    while(*c != '\0')
    {
        if(*c != '%')
        {
            putchar(*c);
            c++;
            continue;
        }

        c++;

        if(*c == '\0')
        {
            break;
        }

        switch(*c)
        {
            case 's': fputs(va_arg(lst, char *), stdout); break;
            case 'c': putchar(va_arg(lst, int)); break;
        }
        c++;
    }
}
1
  • 1
    "c++", loved it
    – Sid110307
    Commented Dec 18, 2021 at 5:21
-1
void print(char *format, ...)
{
    char *traverse;
    unsigned int i;
    char *s;
    va_list arg;
    va_start(arg, format);

    for (traverse = format; *traverse != '\0'; traverse++)
    {
        while (*traverse != '%')
        {
            putchar(*traverse);
            traverse++;
        }
        traverse++;
        switch (*traverse)
        {
        case 's':
            s = va_arg(arg, char *);
            puts(s);
            break;
        case 'c':
            putchar(va_arg(lst, int));
            break;
        }
        va_end(arg);
    }
}
1
  • 1
    Your answer could be improved with additional supporting information. Please edit to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers in the help center.
    – Community Bot
    Commented Aug 9, 2022 at 2:14

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.