'vsnwprintf alternative on linux
What is the direct alternative for the vsnwprintf function on linux machines and what headers should be included to use it?
Thanks for any advice
Solution 1:[1]
Linux variant of this function is snprintf and vsnprintf which are kindly provided by stdio.h:
int snprintf(char *str, size_t size, const char *format, ...);
int vsnprintf(char *str, size_t size, const char *format, va_list args);
and Unicode versions provided by wchar.h:
int swprintf(wchar_t *wcs, size_t maxlen, const wchar_t *format, ...);
int vswprintf(wchar_t *wcs, size_t maxlen, const wchar_t *format, va_list args);
http://linux.die.net/man/3/snprintf
http://linux.die.net/man/3/swprintf
Solution 2:[2]
There’s no alternative for that.
vswprintf suggested in other answers doesn’t tell required buffer length. When you’ll pass nullptr and 0 to the first two arguments, it will returns -1, not the required buffer length. This is both how it's documented, and how it works in practice in clang 4.
There’s a workaround in that answer https://stackoverflow.com/a/16352146/126995 Scroll to the end of that for vscwprintf source code. The workaround works for small strings, but relatively slow for larger strings, and can even exhaust stack space for a very large string.
Solution 3:[3]
Seems that u_vsnprintf() or u_vsnprintf_u() from libicu is what you need
Solution 4:[4]
The truncating version of vswprintf() is unsafe.
You really want the C11 vswprintf_s(), which ensures a null delimited wide string, and errors when the destination buffer is too small.
As you know, the wide variants have no API to calculate the size with a NULL buffer. You need to extend the buffer on errors, if the buffer is too small.
Anyway, safeclib-3.0 will provide all of them. safe and unsafe with --enable-unsafe, wide or non-wide, truncating ('n') or not-truncating. https://github.com/rurban/safeclib/blob/wchar/src/wchar/vsnwprintf_s.c
vsnwprintf is in C99, MSVC, and a few others. Not in musl.
-stc=c99 should be enough for glibc.
Solution 5:[5]
Here an example of workaround:
int vsnwprintf(wchar_t* buffer, size_t size, const wchar_t* format, va_list& params)
{
if(buffer || size)
return vswprintf(buffer, size, format, params);
int result = -1;
for(size = 100; result < 0; size += 100)
{
unique_ptr<wchar_t[]> guard(buffer = new wchar_t[size]);
va_list copy;
va_copy(copy, params);
result = vswprintf(buffer, size, format, copy);
va_end(copy);
}
return result;
};
Probably, it's needed to limit a number of iterations in some way.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | |
| Solution 2 | Soonts |
| Solution 3 | ????????? ?????? |
| Solution 4 | rurban |
| Solution 5 | Serge Roussak |
