I need to allocate a sufficient buffer for format function vswprintf(). When doing the same thing with ANSI string, I'm using:
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. When I execute:
vswprintf( NULL, NULL, pszFormat, args );
result value is always -1.
Only solution which I found is using a large static buffer for calculation required size. 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?
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):
#if !defined(_MSC_VER)
printf_dummy_file = fopen("/dev/null", "wb");
#else
printf_dummy_file = fopen("NUL", "wb");
#endif
...
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++).
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. 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).
Another option is to get rid of the format strings, and instead write to a wostringstream
. But that's not much use if your format string needs to be configured after compile-time.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With