Reputation: 125
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.
Upvotes: 3
Views: 13347
Reputation: 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);
}
}
Upvotes: -1
Reputation: 2859
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++;
}
}
Upvotes: 5