如何在Linux gcc下确定vswprintf的缓冲区大小

lokaqttq  于 2022-11-24  发布在  Linux
关注(0)|答案(4)|浏览(207)

我需要为格式化函数vswprintf()分配一个足够的缓冲区。

vsnprintf( NULL, NULL, pszFormat, args );

返回所需的缓冲区大小。但是这个函数的unicode版本似乎没有这个功能。当我执行:

vswprintf( NULL, NULL, pszFormat, args );

结果值始终为-1
唯一的解决方案,我发现是使用一个大的静态缓冲区计算所需的大小。但我不喜欢这个解决方案:

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字符串所需的缓冲区大小?
此致Ludek

ujv3wf0j

ujv3wf0j1#

打开一个虚拟文件到/dev/null(或者在Windows下为NUL),然后打印到该文件以获取大小,效果非常好(这比打印到字符串要快):

if!已定义(_MSC_VER)

/dev/null”,“wb”)中的一个或多个文件。

#其他
如果您有一个错误,请使用以下命令:
结束字符数
...
n = vfprintf(打印虚拟文件,格式,参数);
“fopen”部分应该执行一次(如果使用的是C++,则可以使用静态变量或全局变量的构造函数)。

iqjalb3h

iqjalb3h2#

有点重量级,但如果没有人提出更好的东西,你可以指数增长的缓冲区,直到它足够大:

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。但如果格式字符串需要在编译时配置,那么这就没有多大用处了。

eqoofvh9

eqoofvh93#

我已经找到了一个仅使用C++的解决方案:
libfmt有它自己sprintf实现,适用于std::stringstd::wstring
例如:

#include <fmt/core.h>
#include <fmt/printf.h>

std::wstring ws = fmt::sprintf(L"The answer is %d.", 42);
gwo2fgha

gwo2fgha4#

这将获得缓冲区大小:
vswprintf(空指针,-1,pszFormat,参数);

相关问题