4

我有一个功能:

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

我想知道所有 myprintf 参数的字节大小,如果它们被打印到缓冲区。我需要动态分配一个数组,我可以打印参数(使用sprinfor _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);

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

谢谢

4

4 回答 4

1

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

对于printf()-like 函数,您需要遍历格式化字符串,解析每个%-code,并添加相应类型的大小。这不会是微不足道的。记住要处理诸如%hdwhich 期望 ashort而不是a 之类的事情int。此外,将值传递给可变参数函数时会发生转换。

于 2012-04-24T12:22:00.310 回答
1

您可以使用vasprintf将所有格式设置为正确大小的缓冲区,它将分配(并且您必须free)。

或者,vsnprintf可用于获取字符串的长度printf将打印:

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

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

于 2012-04-24T14:55:30.567 回答
1

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

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()

于 2012-04-24T15:10:41.713 回答
-2

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

于 2012-04-24T12:30:16.633 回答