2010-11-05 56 views
5

我需要为格式函数vswprintf()分配足够的缓冲区。当使用ANSI字符串做同样的事情时,我正在使用:如何在Linux下确定vswprintf的缓冲区大小gcc

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一起

回答

4

打开一个虚拟文件到/ dev/null的(或NUL windows下),并打印到文件检索大小的作品非常好(比打印到一个字符串更快):

#如果定义(_MSC_VER)
    printf_dummy_file = fopen(“/ dev/null”,“wb”);
#else
    printf_dummy_file = fopen(“NUL”,“wb”);
#ENDIF

...

N = vfprintf(printf_dummy_file,格式参数);

“fopen”部分应该完成一次(如果您使用的是C++,则可以使用静态变量或全局变量的构造函数)。

+1

'vfwprintf'而不是'vfprintf',但无论如何+1。并记住使用va_list的副本。 – 2010-11-13 02:57:17

+0

谢谢你的提示。该解决方案的缺点是比原始函数vswprintf慢5倍。所以我将使用这个函数用于* nix系统,但是对于Win系统来说这是原始的函数。谢谢 – 2010-12-01 11:16:15

1

有点重量级的,但如果没有人来了更好的东西,你可以成倍增长缓冲区,直到它足够大:

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,你” d认为将为缓冲区空间不足定义错误号,并且应该在while条件中检查此错误号,以便其他错误不会导致资源耗尽的循环。但是在http://opengroup.org/onlinepubs/007908775/xsh/fwprintf.html没有定义这样的errno,所以我想你必须测试你实际获得的errno(如果有的话)。

另一种选择是摆脱格式字符串,而是写入wostringstream。但是,如果您的格式字符串需要在编译后进行配置,那没有多大用处。

+0

谢谢你的提示,但它比John Rusta提出的解决方案耗时更多,所以我决定为他的方式。谢谢 – 2010-12-01 11:18:12

-1

这将让缓冲区大小:

vswprintf(nullptr,-1,pszFormat,参数);

+0

这只适用于windows,在Linux上它返回-1 – Programmdude 2015-09-03 04:26:18

+0

@Programmdude:它会为你们所有人返回-1,碰巧在你的代码中有'using namespace std;'的地方(或者使用std :: vswprintf')。对于其他人,它将返回所需的缓冲区大小(或编译器错误)。 – IInspectable 2016-03-29 11:57:03

+0

@IInspectable你的评论是错误的,C++委托给'vswprintf'的C规范而没有指定任何行为改变; C规范说'vswprintf'使得它的未定义行为传递空指针作为第一个参数 – 2016-03-30 00:06:45