16

実際、私はprintf()varag を使用して C で独自のものを作成しようとしています。しかし、私はこれに対する正しい解決策を得ていません。誰でも私を助けることができますか?

4

6 に答える 6

19

printf( ) 関数を実装する前に、可変引数という異常な問題に対処する必要があります。ご存知のように、printf は文字列以外にも多くの引数を取ることができます。したがって、この可変引数の問題を処理するには、stdarg.h という標準ライブラリを使用する必要があります。この実装コンテキストでは、stdarg.h ライブラリ全体を学習する必要はありません。これは、C プログラムで直接理解できるこれらのライブラリのいくつかのマクロ関数を使用するためです。

これは、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); 
}
于 2015-02-18T10:29:18.550 に答える
8

時間があり、本当に興味がある場合は、GNU libc のバージョンを調べることができます: printfを参照してください。これは、vprintf を使用します

于 2009-11-14T19:17:33.227 に答える
3

Linux va_start(3) の man ページには、そのような関数を記述する非常に良い例が示されています (はるかに単純ですが、一般的にすべての主要なブリックがそこにあります)。また、ほぼすべての libstdc 実装を調べることができます。

于 2009-11-14T20:28:04.643 に答える