使用wsprintf将int转换为wchar\t*

使用wsprintf将int转换为wchar\t*,c,wchar-t,C,Wchar T,我正在尝试使用int作为参数格式化wchar\u t*。我在谷歌上搜索了很多,但结果只是更加困惑。所以,考虑这个代码: int main(int argc, char** argv) { wchar_t buf[16]; wsprintf(buf, L"%d", 5); wprintf(L"[%ls]\n", buf); system("pause"); return 0; }; 假设wchar\u t、wsprintf和wprintf分别是char、spr

我正在尝试使用
int
作为参数格式化
wchar\u t*
。我在谷歌上搜索了很多,但结果只是更加困惑。所以,考虑这个代码:

int main(int argc, char** argv) {

   wchar_t buf[16];
   wsprintf(buf, L"%d", 5);
   wprintf(L"[%ls]\n", buf);

   system("pause");
   return 0;

};
假设
wchar\u t
wsprintf
wprintf
分别是
char
sprintf
printf
的宽字符等价物,我希望上面的内容打印
[5]
,但它打印
[/code>和
]之间的垃圾。达到预期结果的正确方法是什么?我在这里误解了什么


(我应该澄清,在这里,可移植性比安全性更重要,因此我想知道一种使用此系列函数而不是更安全的供应商特定扩展的解决方案。)

我觉得您的输出使用了不正确的格式说明符。我猜你会想要

wprintf(L"[%s]\n", buf);
%ls看起来像是一个无效的说明符组合-l表示s“string”类型说明符上的“long int”大小前缀。我在wprintf上找到的文档表明,它将“s”类型说明符视为指向宽字符串(至少对于MS Visual Studio是这样)。

wsprintf()
是Windows特定的函数,在Unix上不可用。您想要实现的功能可以以更便于移植的方式完成(我已经尝试了这个稍微修改过的代码片段,它按照预期工作):

wsprintf()
是微软的混合功能之一。它具有不同的签名,这取决于在预处理期间是否定义了
\u UNICODE
。(引擎盖下发生的事情是,有一个
#ifdef
根据该符号的不存在或存在,将
wsprintf
替换为
wsprintfA
wsprintfW
。)

如果定义了
\u UNICODE
,则它希望缓冲区为
wchar\u t[]


如果未定义
\u UNICODE
(通常为默认值),则它希望缓冲区为
char[]
。这就是这里发生的事情。如果打开了警告,它可能会显示有关不兼容指针类型的警告。垃圾是因为它存储在
buf
中的8位ascii被
wprintf()

解释为Unicode,你怎么知道它是在打印垃圾?您是否将输出通过管道传输到文件中并在十六进制编辑器中查看了它?没有。我假设
wprintf
将以预期的方式将其打印到控制台。不知怎的,这不正确吗?对于我(Mac OS X 10.7.5),
wsprintf()
是不可用的,但是
swprintf()
按预期打印出
[5]
。也许你应该把你的问题改为“关于这段代码我应该持有的正确假设是什么?”@H2CO3谢谢!似乎我误解了这些函数的命名约定
wsprintf
是特定于Windows的,而
swprintf
是实际的宽字符,相当于
sprintf
。您是否愿意将该注释作为答案,以便我将其标记为已接受?
%ls
%hs
对宽字符串和“窄”字符串有效。使用普通的
%s
有点微妙。
#include <wchar.h>
#include <stdio.h>

int main(int argc, char **argv)
{
    wchar_t buf[16];
    swprintf(buf, sizeof(buf) / sizeof(*buf), L"%d", 5);
    wprintf(L"[%ls]\n", buf);

    return 0;
}
[5]