简体   繁体   English

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

[英]How to determine buffer size for vswprintf under Linux gcc

I need to allocate a sufficient buffer for format function vswprintf().我需要为格式 function vswprintf() 分配足够的缓冲区。 When doing the same thing with ANSI string, I'm using:当用 ANSI 字符串做同样的事情时,我使用:

vsnprintf( NULL, NULL, pszFormat, args );

which returns me required size of a buffer.它返回我所需的缓冲区大小。 But it seems that unicode version of this function doesn't have this functionality.但是这个function的unicode版本好像没有这个功能。 When I execute:当我执行时:

vswprintf( NULL, NULL, pszFormat, args );

result value is always -1.结果值始终为 -1。

Only solution which I found is using a large static buffer for calculation required size.我发现的唯一解决方案是使用一个大的 static 缓冲区来计算所需的大小。 But I don't like this solution:但我不喜欢这个解决方案:

static const int nBuffSize = 1024;
static XCHAR evalBuff[nBuffSize];
int nSize = vswprintf( evalBuff, nBuffSize, pszFormat, args );
if ( nSize != -1 )
{
 return nSize;
}
else
{
 throw XXX;
}

Is there any way how to measure required buffer size for unicode strings?有什么方法可以测量 unicode 字符串所需的缓冲区大小?

Regards Ludek问候卢德克

Opening a dummy file to /dev/null (or NUL under windows) and printing to that file to retrieve the size works very well (it is faster than printing to a string): 打开一个虚拟文件到/ dev / null(或Windows下的NUL)并打印到该文件以获取大小,效果很好(比打印到字符串快):

#if !defined(_MSC_VER) #if!defined(_MSC_VER)
printf_dummy_file = fopen("/dev/null", "wb"); printf_dummy_file = fopen(“ / dev / null”,“ wb”);
#else #其他
printf_dummy_file = fopen("NUL", "wb"); printf_dummy_file = fopen(“ NUL”,“ wb”);
#endif #万一

... ...

n = vfprintf(printf_dummy_file, format, args); n = vfprintf(printf_dummy_file,format,args);

The "fopen" part should be done once (you can use a static variable, or the constructor of a global variable if you are using C++). “ fopen”部分应该执行一次(可以使用静态变量,如果使用C ++,则可以使用全局变量的构造函数)。

A bit heavyweight, but if nobody comes up with anything better you could exponentially grow a buffer until it's big enough: 有点重量级,但是如果没有人提出更好的建议,则可以成倍增加缓冲区,直到足够大为止:

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.

Since you're on POSIX, you'd think that an errno would be defined for insufficient buffer space, and that this errno should be checked in the while condition, so that other errors don't cause a resource-hungry loop. 由于您使用的是POSIX,因此您会认为会为缓冲区空间不足定义一个errno,并且应该在while条件下检查该errno,以免其他错误不会导致资源紧张的循环。 But there's no such errno defined at http://opengroup.org/onlinepubs/007908775/xsh/fwprintf.html , so I guess you'll have to test what errno you actually get on your implementation (if any). 但是在http://opengroup.org/onlinepubs/007908775/xsh/fwprintf.html上没有定义这样的errno,所以我想您必须测试实现时实际得到的errno(如果有)。

Another option is to get rid of the format strings, and instead write to a wostringstream . 另一种选择是摆脱格式字符串,而是写入wostringstream But that's not much use if your format string needs to be configured after compile-time. 但是,如果您需要在编译后配置格式字符串,那将没有太大用处。

I have found a C++ only solution:我找到了一个只有 C++ 的解决方案:
libfmt has its own sprintf implementation, applicable to both std::string and std::wstring . libfmt有自己的 sprintf 实现,适用于std::stringstd::wstring
Ex:前任:

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

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

This will get the buffer size: 这将获得缓冲区大小:

vswprintf(nullptr, -1, pszFormat, args); vswprintf(nullptr,-1,pszFormat,args);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM