web-dev-qa-db-ja.com

va_listを使用してprintfを呼び出す

void TestPrint(char* format, ...)
{
    va_list argList;

    va_start(argList, format);
    printf(format, argList);
    va_end(argList);
}


int main()
{
    TestPrint("Test print %s %d\n", "string", 55);
    return 0;
}

私は取得する必要があります:

Test print string 55

実際、ガベージ出力が得られます。このコードの何が問題になっていますか?

45
Alex F

代わりに vprintf() を使用してください。

72

Printfの代わりに、この特定の目的のために作成されたvprintfを代わりに試すことをお勧めします。

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

void errmsg( const char* format, ... )
{
  va_list arglist;

  printf( "Error: " );
  va_start( arglist, format );
  vprintf( format, arglist );
  va_end( arglist );
}

int main( void )
{
  errmsg( "%s %d %s", "Failed", 100, "times" );
  return EXIT_SUCCESS;
}

ソース: http://www.qnx.com/developers/docs/6.5.0/index.jsp?topic=/com.qnx.doc.neutrino_lib_ref/v/vprintf.html

58
onteria_

他の人がすでに指摘したように:この場合、代わりにvprintfを使用する必要があります。

しかし、本当にprintfをラップしたい場合、またはv...バージョンを持たない関数をラップしたい場合は、非標準の__builtin_apply機能を使用してGCCでそれを行うことができます。

int myfunction(char *fmt, ...)
{
    void *arg = __builtin_apply_args();
    void *ret = __builtin_apply((void*)printf, arg, 100);
    __builtin_return(ret);
}

__builtin_applyの最後の引数は最大です。引数の合計サイズ(バイト単位)。ここで十分な大きさの値を使用してください。

23
CliffordVienna

これは、printf()の使用方法ではありません。 _va_lists_を使用する場合は、代わりにvprintf()を使用します。 こちら 参照を見てください。

5
Constantinius