自家製可変長引数関数

[戻る]
DOSKOI-PANDA 2003/11/14(金) 11:22:08
Win2K VC++6.0 SP5 です。

タイトル内容の関数を自作したくて以下のプロトタイプを作成しました。
が、結果がうまくいきません。

int MySprintf(LPTSTR lpszBuffer, LPCTSTR lpszFormat, ...)
{
    va_list arg_list;
    va_start(arg_list, lpszFormat);
    int nResult = sprintf(lpszBuffer, lpszFormat, arg_list);
    va_end(arg_list);
    return nResult;
}

void CTestDlg::OnBtnSprintf() 
{
    CString strMessage;
    strMessage.Format("str = %s, val = %d\n", "AAA", 1);
    TCHAR szBuffer[100];
    sprintf(szBuffer, "str = %s, val = %d\n", "AAA", 1);
    TRACE(szBuffer);
    MySprintf(szBuffer, "str = %s, val = %d\n", "AAA", 1);
    TRACE(szBuffer);
}

<TRACE出力>
str = AAA, val = 1
str =  cA, val = 1242992

デバッガで sprintf 内部まで入ってみましたが、lpszFormat は正しい値で
引き渡されているのを確認しました。可変長引数部分を受け取る va_list で
宣言されている sprintf の内部変数にはよく解らない16進値が設定されてい
ました。

MSDN見ても、過去ログ見ても、CString::Format() の中をみても、

va_list で宣言して、
va_start で可変長引数の1つ前に va_list の変数設定して、
sprintf に渡して、
va_end で後始末

という手順は同じですし、間違いをやらかしてるようには見えないのですが...

どなたか間違いを指摘できる方いらっしゃいましたらお願いします。

(「可変長引数」って用語として正しいのかしら?)

επιστημη [E-Mail] [HomePage] 2003/11/14(金) 11:23:58
sprintf じゃなくて vsprintf ではありませんか?

DOSKOI-PANDA 2003/11/14(金) 11:48:31
[[解決]]
επιστημηさん、ありがとうございました。
うまくいきました。

MSDN見てみると、
sprintf の宣言は可変部分の引数が ... とあいまいな宣言なのに
vsprintf の方は va_list と明確に宣言されていますね。

sprintf みたいな関数を作る場合、

... でもらって、
va_list にして、
va_list 引数を取る関数に渡す

という手順になるのですね。

勉強になりました。
ありがとうございました。

古いスレッドには追加発言できません。