2

以下几行都“按预期工作”:

wchar_t u[50], v[50];

swprintf(u, 50, L"%s", L"hello");
swprintf(v, 50, L"%ls", L"goodbye");

MessageBoxW(NULL, u, v, MB_OK);   // output: MessageBox showing "hello" and "goodbye"

有没有办法打印一个窄字符串,这方面的文档在哪里?例如

swprintf(u, 50, L"%?", "hello");

C++ 标准指定(通过引用 C 标准)在wprintf函数族中%s指定一个字符串char(在多字节编码中,例如 UTF-8),并%ls指定一个wchar_t.

所以 RTL(C++Builder 提供的运行时库实现)在这里显然不符合标准。

背景:我实际上正在尝试使用UnicodeString::sprintf,但是将繁重的工作委托给vswprintf.

4

2 回答 2

2

这不是一个真正的答案,而是更多的元素汇编。

参考 :

网站http://www.cplusplus.com/很清楚:对于wprintf家庭:...所有格式说明符的含义与 printf 中的相同;因此,应使用 %lc 编写宽字符(而不是 %c),以及应使用 %ls 编写宽字符串(而不是 %s)

实施:

gcc 和 clang 都符合上述规范

MSVC 和根据 OP Borland C++ 不符合并接受%s宽字符串。

于 2015-01-13T12:31:01.053 回答
1

我设法vprinter.c在 RTL 源代码的文件中找到了这个(C++Builder 带有自己的 RTL,它不引用 MS):

            /* The 's' conversion takes a string (char *) as
             * argument and copies the string to the output
             * buffer.
             *
             * Note: We must handle both narrow and wide versions
             * depending on the flags specified and the version called:
             *
             * Format           printf          wprintf
             * ----------------------------------------
             * %s               narrow          wide
             * %S               wide            narrow
             * %hs              narrow          narrow
             * %hS              narrow          narrow
             * %ls              wide            wide
             * %lS              wide            wide
             *
             */

所以代码:

swprintf(v, 50, L"%hs", "hello");

生成正确的输出。

但是,这不会进行任何 UTF-8 转换;通过附加空字节来“加宽”窄字符。(通过检查来源的结果来确认)。

于 2015-01-13T11:19:08.443 回答