count_sprintf的MSVC / Linux代码

时间:2011-03-03 17:48:39

标签: c++ c visual-c++ stdio

我需要返回
的函数count_sprintf() 在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 个答案:

答案 0 :(得分: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
}

答案 1 :(得分:1)

我不知道你是否需要C解决方案,C ++或两者兼而有之。

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

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

答案 2 :(得分: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.

答案 3 :(得分:0)

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