C 中对可变参数函数的级联调用

问题描述 投票:0回答:2

我需要制作

vprintf
的包装,以便可以完成类似 printf 的函数的多个实现。这段代码演示了这个问题:

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

void print_fmt2(const char *fmt, ...)
{
    va_list args;
    va_start(args, fmt);
    vprintf(fmt, args);
    va_end(args);
}


void print_fmt1(const char *fmt, ...)
{
    va_list args, args_copy;
    va_start(args, fmt);
    va_copy(args_copy, args);
    print_fmt2(fmt, args_copy);
    va_end(args_copy);
    va_end(args);
    print_fmt2("\r\n");
}


int main ()
{
  print_fmt1("test return %s %u\r\n", "is", 0);
  return 0;
}

上面的代码,使用 gcc 11.4,Linux 编译,输出:

test return 3447949600

但我期望和想要实现的是:

test return is 0

问题应该是使用

va_copy
宏,但我不知道出了什么问题。

我必须遵守C99标准。

有什么想法吗?

谢谢。

c variadic-functions c99
2个回答
3
投票

你不能那样做。

这就是为什么标准可变参数函数总是有两种变体:一种可变参数函数,另一种采用

va_list
参数。

就像在您展示的示例中一样,有

vprintf
使用
va_list
参数。如果你想“级联”你的函数,你需要对它们做同样的事情。

所以你需要有例如

void print_fmt2(const char *fmt, va_list args)
{
    vprintf(fmt, args);
}

void print_fmt1(const char *fmt, ...)
{
    va_list args;
    va_start(args, fmt);
    print_fmt2(fmt, args);
    va_end(args);
}

0
投票

你不能这样做,但你可以使用宏来归档你想要的东西:

void print_fmt2(const char *fmt, ...)
{
    va_list args;
    va_start(args, fmt);
    vprintf(fmt, args);
    va_end(args);
}


#define print_fmt1(...) \
{                               \
    print_fmt2(__VA_ARGS__);    \
    print_fmt2("\r\n");         \
}


int main ()
{
  print_fmt1("test return %s %u\r\n", "is", 0);
  return 0;
}
© www.soinside.com 2019 - 2024. All rights reserved.