在尝试输出一些计数的字符串时,我在Microsoft的sprintf()
和wsprintf(
)函数之间遇到以下不对称性:
#define _UNICODE
sprintf(buff, "%.3s", "abcdef"); //Outputs: "abc"
sprintf(buff, "%.*s", 3, "abcdef"); //Outputs: "abc"
wsprintf(buff, L"%.3s", L"abcdef"); //Outputs: L"abc"
wsprintf(buff, L"%.*s", 3, L"abcdef"); //Outputs: L"*s"
请注意,最后一个wsprintf()
不会像带有相同(但较宽)参数的窄姐妹函数L"abc"
一样输出sprintf()
。
问:这是错误还是功能?
注意:这类似于此处描述的问题: Formatting differences between sprintf() and wsprintf() in VS2015
答案 0 :(得分:1)
wsprintf
很老,很老。它无法精确记录*
,因此请勿将格式字符串传递给wsprintf
。您的测试在技术上未指定。
请注意,wsprintf
不会在buff
中写入超过1023个字符,后跟空字符,并且使用UCS-2而不是UTF-16。此函数的设计是为您传递一个固定大小的1024堆栈缓冲区,并且不必担心缓冲区溢出,因为它会为您截断。
就我的意图而言,它更倾向于使调试消息传递到MessageBox
,而不是用于实际的应用程序。这是snprintf
的简化形式,带有固定的n
,该实现独立于其他标准库而实现。
好的,因此您希望始终为null的swprintf
终止。试试这个:
int swprintf2(wchar_t *ws, size_t len, const wchar_t* format, ...)
{
va_arg arg;
va_start(arg, format);
ws[len - 1] = 0;
return vswprintf(ws, len - 1, format, arg);
}