在linux机器上,vsnwprintf函数的直接替代方法是什么?使用它应该包含什么头文件?多谢指教
vsnwprintf
nkcskrwz1#
这取决于vsnwprintf()(sic) 的功能及其参数列表。The C99 Standard describes vswprintf() (in section 7.24.2.7). To use it you need to #include <stdarg.h> and <wchar.h> . The implementation should be in the Standard library.
vsnwprintf()
vswprintf()
<stdarg.h>
<wchar.h>
pqwbnv8z2#
此函数的Linux变体是snprintf和vsnprintf,它们由stdio.h提供:
snprintf
vsnprintf
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);
和wchar.h提供的Unicode版本:
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/snprintfhttp://linux.die.net/man/3/swprintf
xggvc2p63#
没有别的选择。在其他答案中建议的vswprintf并没有给出所需的缓冲区长度。当你将nullptr和0传递给前两个参数时,它将返回-1,而不是所需的缓冲区长度。这既是documented的工作原理,也是它在clang 4中的实际工作原理。在这个答案中有一个解决方法https://stackoverflow.com/a/16352146/126995滚动到vscwprintf源代码的结尾。这个解决方法适用于小字符串,但是对于较大的字符串来说相对较慢,对于非常大的字符串甚至会耗尽堆栈空间。
vecaoik14#
看起来libicu中的u_vsnprintf()或u_vsnprintf_u()是您需要的
iqih9akk5#
vswprintf()的截断版本是不安全的。您确实需要C11 vswprintf_s(),它可以确保空分隔的宽字符串,并在目标缓冲区太小时出错。如您所知,wide变体没有API来计算空缓冲区的大小。如果缓冲区太小,您需要在出错时扩展缓冲区。无论如何,safeclib-3.0都将提供所有这些选项。safe和unsafe with --enable-unsafe、宽或非宽、截断('n')或不截断。https://github.com/rurban/safeclib/blob/wchar/src/wchar/vsnwprintf_s.cvsnwprintf在C99,MSVC和其他几个中。不在musl中。-stc=c99对glibc应该足够了。
vswprintf_s()
-stc=c99
yizd12fk6#
下面是一个解决方法示例:
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; };
也许,它需要以某种方式限制迭代的次数。
j8ag8udp7#
对于C++,可以使用<fmt/printf.h>中libfmt的fmt::sprintf
<fmt/printf.h>
fmt::sprintf
7条答案
按热度按时间nkcskrwz1#
这取决于
vsnwprintf()
(sic) 的功能及其参数列表。The C99 Standard describes
vswprintf()
(in section 7.24.2.7). To use it you need to #include<stdarg.h>
and<wchar.h>
. The implementation should be in the Standard library.pqwbnv8z2#
此函数的Linux变体是
snprintf
和vsnprintf
,它们由stdio.h
提供:和
wchar.h
提供的Unicode版本:http://linux.die.net/man/3/snprintf
http://linux.die.net/man/3/swprintf
xggvc2p63#
没有别的选择。
在其他答案中建议的vswprintf并没有给出所需的缓冲区长度。当你将nullptr和0传递给前两个参数时,它将返回-1,而不是所需的缓冲区长度。这既是documented的工作原理,也是它在clang 4中的实际工作原理。
在这个答案中有一个解决方法https://stackoverflow.com/a/16352146/126995滚动到vscwprintf源代码的结尾。这个解决方法适用于小字符串,但是对于较大的字符串来说相对较慢,对于非常大的字符串甚至会耗尽堆栈空间。
vecaoik14#
看起来libicu中的u_vsnprintf()或u_vsnprintf_u()是您需要的
iqih9akk5#
vswprintf()
的截断版本是不安全的。您确实需要C11vswprintf_s()
,它可以确保空分隔的宽字符串,并在目标缓冲区太小时出错。如您所知,wide变体没有API来计算空缓冲区的大小。如果缓冲区太小,您需要在出错时扩展缓冲区。
无论如何,safeclib-3.0都将提供所有这些选项。safe和unsafe with --enable-unsafe、宽或非宽、截断('n')或不截断。https://github.com/rurban/safeclib/blob/wchar/src/wchar/vsnwprintf_s.c
vsnwprintf
在C99,MSVC和其他几个中。不在musl中。-stc=c99
对glibc应该足够了。yizd12fk6#
下面是一个解决方法示例:
也许,它需要以某种方式限制迭代的次数。
j8ag8udp7#
对于C++,可以使用
<fmt/printf.h>
中libfmt的fmt::sprintf