Monday, July 23, 2012

How to write your own "printf()" function in C.

This is one of the most frequently asked interview questions. Here is a C program which implements a basic version of printf(). This is a really, really simplified version of printf(). Note carefully how floating point and other complicated support has been left out. Also, note how we use low level puts() and putchar(). Don't make a fool of yourself by using printf() within the implementation of printf()!!!!!!!!!!!!!!!!!!!!!!

#include <stdio.h>
#include <stdarg.h>

char *convert(unsigned int, int);

int main()
{
    void myprintf(char *,...);
    char * convert(unsigned int, int);
    int i = 75;
    char str[]="Lets ready for interview";
    myprintf("\nMessage = %s%d%x",str,i,i);
    return 0;
}

void myprintf(char * fmt,...)
{
    char *p;
    int i;
    unsigned u;
    char *s;

    va_list argp;
    va_start(argp, fmt);

    p = fmt;

    for(p=fmt; *p!='\0';p++)
    {
        if(*p != '%')
        {
            putchar(*p);continue;
        }

        p++;

        switch(*p)
        {
             case 'c' :
                       i = va_arg(argp,int);
                       putchar(i);
                       break;
             case 'd' :
                       i = va_arg(argp,int);
                       if(i<0)
                       {
                            i = -i;
                            putchar('-');
                       }
                       puts(convert(i,10));
                       break;
             case 'o':
                       i = va_arg(argp,unsigned int);
                       puts(convert(i,8));
                       break;
             case 's':
                       s = va_arg(argp,char *);
                       puts(s);
                       break;
             case 'u':
                       u=va_arg(argp, unsigned int);
                       puts(convert(u,10));
                       break;
             case 'x':
                       u=va_arg(argp, unsigned int);
                       puts(convert(u,16));
                       break;
             case '%':
                       putchar('%');
                       break;
          }
      }

      va_end(argp);
}

char *convert(unsigned int num, int base)
{
   static char buf[33];
   char *ptr;

   ptr=&buf[sizeof(buf)-1];
   *ptr='\0';
   do
   {
       *--ptr = "0123456789abcdef"[num%base];
       num/=base;
   }while(num!=0);
   return(ptr);
}

No comments:

Post a Comment