681ankit
681ankit

Reputation: 3

cant find error in printf function

following is code of function

void printf(char *ch,void *num,...)
         {
    int i;
    va_list ptr;    //to store variable length argument list
    va_start(ptr,num); // initialise ptr


    for(i=0;ch[i]!='\0';i++)
        {


            if(ch[i]=='%')  // check for % sign in print statement
                { i++;

                    if( ch[i]=='d')
                        {  
                          int *no = (int *)va_arg(ptr,int * );
                          int value=*no;  // just used for nothing 
                          printno(value);  //print int number

                        }
                    if( ch[i]=='u')
                        {

                           unsigned long *no =(unsigned long *) va_arg(ptr,unsigned long *);
                           unsigned long value=*no;
                           printuno(value);  //print unsigned long


                        }
                }
            else    // if not % sign then its regular character so print it
                {
                    printchar(ch[i]);
                }
        }




}

this my code for printf() to print integer value and uint values

It is working fine for string portion in arguments but for %d %u it shows the same values for all variables. This value is 405067 - even though the values of the variables are different. Please tell me how to fix this.

Upvotes: 0

Views: 364

Answers (2)

Jonathan Leffler
Jonathan Leffler

Reputation: 755026

As noted in a comment, the C99 prototype for printf() is:

int printf(const char * restrict format, ...);

Therefore, if you're calling your function printf(), you should probably follow its design. I'm going to ignore flags, field width, precision and length modifiers, assuming that the conversion specifiers are simply two characters each, such as %d or %%.

int printf(const char * restrict format, ...)
{
    va_list args;
    va_start(args, format);
    char c;
    int len = 0;

    while ((c = *format++) != '\0')
    {
        if (c != '%')
        {
            putchar(c);
            len++;
        }
        else if ((c = *format++) == '%')
        {
            putchar(c);
            len++;
        }
        else if (c == 'd')
        {
            int value = va_arg(args, int);
            len += printno(value);
        }
        else if (c == 'u')
        {
            unsigned value = va_arg(args, unsigned);
            len += printuno(value);
        }
        else
        {
            /* Print unrecognized formats verbatim */
            putchar('%');
            putchar(c);
            len += 2;
        }
    }
    return len;
}

Dealing with the full set of format specifiers (especially if you add the POSIX n$ notation as well as flags, field width, precision and length modifiers) is much harder, but this should get you moving in the correct direction. Note that I assume the printno() and printuno() functions both report how many characters were written for the conversion specifier. The function returns the total number of characters written. Note, too, that production code would need to allow for the called functions to fail, and would therefore probably not use the len += printno(value); notation, but would capture the return from printno() into a separate variable that could be tested for an error before adding it to the total length output.

Upvotes: 0

Lily Ballard
Lily Ballard

Reputation: 185841

Why are you interpreting the argument as a pointer? I'm surprised you aren't crashing. You should just be using

int num = va_arg(ptr,int);
printno(num);

and

unsigned int num = va_arg(ptr,unsigned int);
printuno(value);

(note, unsigned int, not unsigned long, because that would actually be %lu)

Also, get rid of the num parameter. It's wrong. Your va_list should be initialized as

`va_start(ptr, ch);`

va_start() takes the last argument before the varargs, not the first argument.

Upvotes: 1

Related Questions