How to write my own printf() in C?

早过忘川 提交于 2019-11-30 06:38:16

问题


Actually I am trying to write my own printf() in C by using varags. But I am not getting the correct solution for this. Can anyone help me out?


回答1:


Before implementation of printf( ) function we have to deal with unusual problem which is variable arguments. As we know that printf can take many arguments besides string. So we have to use a standard library called stdarg.h to handle this variable argument problem. In this implementation context, we don’t need learn whole stdarg.h library because we use some macro functions of these library which is understandable directly by our C program.

Here is the code source which explain nice and fast

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

void Myprintf(char *,...);              //Our printf function
char* convert(unsigned int, int);       //Convert integer number into octal, hex, etc.


int main() 
{ 
    Myprintf(" WWW.FIRMCODES.COM \n %d", 9); 

    return 0;
} 


void Myprintf(char* format,...) 
{ 
    char *traverse; 
    unsigned int i; 
    char *s; 

    //Module 1: Initializing Myprintf's arguments 
    va_list arg; 
    va_start(arg, format); 

    for(traverse = format; *traverse != '\0'; traverse++) 
    { 
        while( *traverse != '%' ) 
        { 
            putchar(*traverse);
            traverse++; 
        } 

        traverse++; 

        //Module 2: Fetching and executing arguments
        switch(*traverse) 
        { 
            case 'c' : i = va_arg(arg,int);     //Fetch char argument
                        putchar(i);
                        break; 

            case 'd' : i = va_arg(arg,int);         //Fetch Decimal/Integer argument
                        if(i<0) 
                        { 
                            i = -i;
                            putchar('-'); 
                        } 
                        puts(convert(i,10));
                        break; 

            case 'o': i = va_arg(arg,unsigned int); //Fetch Octal representation
                        puts(convert(i,8));
                        break; 

            case 's': s = va_arg(arg,char *);       //Fetch string
                        puts(s); 
                        break; 

            case 'x': i = va_arg(arg,unsigned int); //Fetch Hexadecimal representation
                        puts(convert(i,16));
                        break; 
        }   
    } 

    //Module 3: Closing argument list to necessary clean-up
    va_end(arg); 
} 

char *convert(unsigned int num, int base) 
{ 
    static char Representation[]= "0123456789ABCDEF";
    static char buffer[50]; 
    char *ptr; 

    ptr = &buffer[49]; 
    *ptr = '\0'; 

    do 
    { 
        *--ptr = Representation[num%base]; 
        num /= base; 
    }while(num != 0); 

    return(ptr); 
}



回答2:


If you have some time and are really curious you could study the GNU libc's version: See printf, which in turn uses vprintf, which uses vfprintf




回答3:


Linux va_start(3) man page gives very good example of writing such functions (much more simpler but in general all the major bricks are there). Also you could examine almost any libstdc implementation.




回答4:


There are at least two books with good explanations of how a printf()-like formatting function can be written (and complete working examples):

  • Plauger, 'The Standard C Library'
  • Hanson, 'C Interfaces and Implementations'



回答5:


This answer may help you to understand how to write variadic functions. Note, no error / bounds checking is done, no attributes are set to tell the compiler what kind of arguments might be suitable, no benefit over just using printf() is achieved.

It may or may not be the example you are looking for.

The relevant snippet (expanded a bit here):

#include <stdarg.h>
void _printf(FILE *out, va_list ap)
{
    vfprintf(out, fmt, ap);
}

void printf(const char *fmt, ...)
{
    va_list ap;
    va_start(ap, fmt);
    _printf(stdout, ap);
    va_end(ap);
}

Note: making these return the correct type (signed integer) is left as an exercise for the reader. This looks a lot like homework to me, I'm just trying to get you past any sticking point of using va_start and va_end, plus showing that a va_list can be passed to helper functions to avoid duplicating code in so many implementations of almost the same thing.

I strongly advise looking at the BSD (or even glibc) printf sub system implementation. You could also look at uclibc, dietlibc, etc ..



来源:https://stackoverflow.com/questions/1735236/how-to-write-my-own-printf-in-c

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!