在 C++Builder 中使用 swprintf 打印窄字符串

Print narrow strings using swprintf in C++Builder

本文关键字:打印 字符串 swprintf C++Builder      更新时间:2023-10-16

以下行都"按预期工作":

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

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

参考:

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

实现:

GCC 和 Clang 均符合上述规范

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

我设法在 RTL 源代码的vprinter.c文件中找到了这个(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 转换;窄字符通过附加空字节来"加宽"。(通过检查来源的检索来确认)。