0

以下は関数のコードです

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]);
                }
        }




}

これは、printf() が整数値と uint 値を出力するための私のコードです。

引数の文字列部分では正常に機能していますが、 %d %u の場合、すべての変数に対して同じ値が表示されます。変数の値は異なりますが、この値は 405067 です。これを修正する方法を教えてください。

4

2 に答える 2

1

なぜ引数をポインタとして解釈しているのですか?あなたが墜落していないことに驚いています。あなたはただ使うべきです

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

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

(注、、unsigned intではなくunsigned long、実際にはそうなるため%lu

また、numパラメータを削除します。それは間違っています。次のva_listように初期化する必要があります

`va_start(ptr, ch);`

va_start()最初の引数ではなく、varargsの前の最後の引数を取ります。

于 2012-08-17T06:44:44.020 に答える
0

コメントで述べたように、C99 プロトタイプprintf()は次のとおりです。

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

したがって、関数を呼び出す場合はprintf()、おそらくその設計に従う必要があります。フラグ、フィールド幅、精度、および長さの修飾子は無視します。変換指定子は、%dまたは%%.

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;
}

フォーマット指定子の完全なセット (特にPOSIX 表記とフラグ、フィールド幅、精度、および長さの修飾子を追加する場合) を扱うのn$ははるかに困難ですが、これにより正しい方向に進むことができます。printno()printuno()関数の両方が、変換指定子に書き込まれた文字数を報告すると仮定していることに注意してください。この関数は、書き込まれた文字の総数を返します。また、本番コードでは、呼び出された関数が失敗することを許可する必要があるため、おそらくこの表記法は使用しませんが、合計に追加する前にエラーをテストできる別の変数にlen += printno(value);からの戻り値をキャプチャすることに注意してください。printno()長さの出力。

于 2012-08-17T09:31:55.693 に答える