使用va_list调用printf

Ale*_*x F 49 c printf variadic-functions

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;
}
Run Code Online (Sandbox Code Playgroud)

我需要得到:

Test print string 55
Run Code Online (Sandbox Code Playgroud)

实际上,我得到了垃圾输出.这段代码有什么问题?

Oli*_*rth 73

vprintf()改用.

  • @PingwinTux:是的.这种反应在2011年可以接受;) (4认同)

ont*_*ia_ 60

而不是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;
}
Run Code Online (Sandbox Code Playgroud)

资料来源:http://www.qnx.com/developers/docs/6.5.0/index.jsp?topic = / com.qnx.doc.neutrino_lib_ref/v/vprintf.html


Cli*_*nna 22

正如其他人已经指出的那样:在这种情况下你应该使用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);
}
Run Code Online (Sandbox Code Playgroud)

最后一个参数__builtin_apply是最大值.参数的总大小(以字节为单位).确保在此处使用足够大的值.

  • 感谢您的回答,它可以直接解决OP的问题。出于拦截目的,此代码挽救了我的生命!(或至少避免让我推迟装配:) (2认同)
  • 这个值有没有最大值?`_builtin_apply()`应该解析调用堆栈帧,以便自己找出值.但这取决于架构是否以及如何有效.我曾为自己嫁接过类似的解决方案.那太差了. (2认同)

Con*_*ius 5

这不是你如何使用printf().如果您想使用va_lists,请vprintf()改用.看这里参考.