[英]vswprintf() without buffer size crashes on small buffer instead of EOF. How to pass buffer size
[英]How to determine buffer size for vswprintf under Linux gcc
我需要为格式 function vswprintf() 分配足够的缓冲区。 当用 ANSI 字符串做同样的事情时,我使用:
vsnprintf( NULL, NULL, pszFormat, args );
它返回我所需的缓冲区大小。 但是这个function的unicode版本好像没有这个功能。 当我执行时:
vswprintf( NULL, NULL, pszFormat, args );
结果值始终为 -1。
我发现的唯一解决方案是使用一个大的 static 缓冲区来计算所需的大小。 但我不喜欢这个解决方案:
static const int nBuffSize = 1024;
static XCHAR evalBuff[nBuffSize];
int nSize = vswprintf( evalBuff, nBuffSize, pszFormat, args );
if ( nSize != -1 )
{
return nSize;
}
else
{
throw XXX;
}
有什么方法可以测量 unicode 字符串所需的缓冲区大小?
问候卢德克
打开一个虚拟文件到/ dev / null(或Windows下的NUL)并打印到该文件以获取大小,效果很好(比打印到字符串快):
#if!defined(_MSC_VER)
printf_dummy_file = fopen(“ / dev / null”,“ wb”);
#其他
printf_dummy_file = fopen(“ NUL”,“ wb”);
#万一
...
n = vfprintf(printf_dummy_file,format,args);
“ fopen”部分应该执行一次(可以使用静态变量,如果使用C ++,则可以使用全局变量的构造函数)。
有点重量级,但是如果没有人提出更好的建议,则可以成倍增加缓冲区,直到足够大为止:
std::vector<wchar_t> vec(512);
int nSize;
do {
vec.resize(vec.size()*2);
va_list args2;
va_copy args2, args;
nSize = vswprintf(&vec[0], vec.size(), format, args2);
va_end args2
} while(nSize < 0);
// now I have the length, and the formatted string to copy if required.
由于您使用的是POSIX,因此您会认为会为缓冲区空间不足定义一个errno,并且应该在while
条件下检查该errno,以免其他错误不会导致资源紧张的循环。 但是在http://opengroup.org/onlinepubs/007908775/xsh/fwprintf.html上没有定义这样的errno,所以我想您必须测试实现时实际得到的errno(如果有)。
另一种选择是摆脱格式字符串,而是写入wostringstream
。 但是,如果您需要在编译后配置格式字符串,那将没有太大用处。
我找到了一个只有 C++ 的解决方案:
libfmt有自己的 sprintf 实现,适用于std::string
和std::wstring
。
前任:
#include <fmt/core.h>
#include <fmt/printf.h>
std::wstring ws = fmt::sprintf(L"The answer is %d.", 42);
这将获得缓冲区大小:
vswprintf(nullptr,-1,pszFormat,args);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.