VS2017中带有“%。* s”的sprintf与wsprintf

时间:2019-04-14 23:19:42

标签: c windows visual-studio-2017

在尝试输出一些计数的字符串时,我在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

1 个答案:

答案 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);
}