0

我需要函数 count_sprintf() 应该返回
格式化缓冲区所需的字符数(不是 inc nul 字节),在 Win32 和 Linux 上。

int count_sprintf(const char *format, va_list ap);

当格式化值长于缓冲区大小时,vsnprintf 的返回值在 Win32 与 Linux 之间存在细微差异。这就是我寻求帮助的原因。

你能为这个功能提供可移植的代码(#ifdef WIN32)吗?

要像这样使用的函数:

int bufsize = 1 + count_snprintf(format, ap);  
char *buf = (char*)malloc(bufsize);  
vsnprintf(buf, bufsize, format, ap); // on WIN32, _vsnprint, on Linux, vsnprintf.

谢谢

4

4 回答 4

3

VS 运行时有 _vscprintf 计算所需字符数。

int count_sprintf(const char *format, va_list ap) {
#ifdef WIN32
  return _vscprintf(format, ap);
#else
  char c;
  return vsnprintf(&c, 1, format, ap);
#endif
}
于 2011-03-03T18:04:04.740 回答
1

我不知道您是否想要 C 解决方案、C++ 或两者兼而有之。

在 C++ 中有一个非常简单的方法可以解决这个问题:使用流而不是printf函数行。

在 CI 中建议强烈注意使用可变格式字符串的任何情况:如果函数的 varargs 稍微偏离一点并且编译器无法帮助您,它们很可能会导致问题。如果格式是在外部生成的,那就更糟了,因为您基本上对任何数量的缓冲区溢出漏洞都持开放态度。至少如果你有一个固定的格式字符串,你知道它会开始多长时间,并且一些编译器可以对可变参数进行格式字符串检查。

于 2011-03-03T17:57:23.290 回答
0

在 Linux 上,您可以使用asprintf

   The  functions asprintf() and vasprintf() are analogs of sprintf(3) and
   vsprintf(3), except that they allocate a string large  enough  to  hold
   the output including the terminating null byte, and return a pointer to
   it via the first argument.  This pointer should be passed to free(3) to
   release the allocated storage when it is no longer needed.
于 2011-03-03T17:51:34.967 回答
0

您可以为此使用 vsnprintf - 如果您给它一个大小为 0 的缓冲区,它实际上不会尝试在缓冲区中放入任何内容,但仍会返回它将输出的字符数

于 2011-03-03T18:41:34.260 回答