省略号函数参数的大小(以字节为单位)

Size in bytes of ellipsis function arguments

本文关键字:字节 为单位 函数 参数 省略号      更新时间:2023-10-16

我有一个函数:

static int myprintf(const char* fmt, ...)

我想知道所有 myprintf 参数的大小(以字节为单位),如果它们被打印到缓冲区。我需要动态分配一个数组,我可以将参数打印到该数组(使用 sprinf_vsprinf)例如在 32 位操作系统中,对于 myprintf("%d %c",10,'a');myprintf 参数的大小为 5。

我尝试像这样实现它:

va_list ap;
va_start(ap, fmt);
myArgSize(ap);

有人可以建议如何实现myArgSize吗?

我被告知要尝试这样的事情

char c;
int len = ::_vsnprintf(&c, 1, fmt, ap);

它不起作用,因为写入了多个字节。但可能有一些解决方法。

谢谢

尽管您的大部分问题都是关于传递给三元函数的参数的大小,但在我看来,您实际上对输出缓冲区需要多大感兴趣。 尝试如下操作:

va_list ap;
va_start(ap, fmt);
int len = ::vsnprintf( NULL, 0, fmt, ap);
if (len < 0) abort();
char* buffer = (char*) malloc( len + 1);
if (!buffer) abort();
::vsnprintf( buffer, len+1, fmt, ap);
va_end();

但是,如果您的平台没有符合 C99 标准的vsnprintf()(例如 MSVC),则必须进行一些调整。对于 MSVC,您可以尝试传入一个带有猜测大小的缓冲区(可能是strlen(fmt)+1 + (10 * number_of_percent_signs_in_fmt),或者只是从一个应该涵盖 99% 的情况的大小开始 - 也许是 200 ),并增加猜测,直到它起作用。或者你可以尝试Holger Weiss的snprintf()系列函数。

嗯...有关参数类型和顺序的唯一信息在第一个参数中;这就是为什么它是必需的。

对于类似printf()的函数,您需要单步执行格式化字符串,解析每个%代码,并添加相应类型的大小。这不会是微不足道的。请记住处理诸如%hd这样期望short而不是int的事情。此外,当值传递给可变参数函数时,也会发生转换。

您可以使用

vasprintf将所有格式设置到正确大小的缓冲区中,它将分配该缓冲区(并且您必须free)。

或者,可以使用vsnprintf来获取printf打印的字符串的长度:

int n = vsnprintf(NULL, 0, fmt, args);

这是因为如果有足够的空间,它会返回它将打印的字节数。在这种情况下,它无法打印任何内容,但无论如何都会返回数字。

您可以使用 sizeof(type_name) 并使用 for 循环遍历所有参数,type_name是 C 数据类型中的任何一种,如 int、float、long 等。然后添加所有字节,