好的,我有这个:
AllocConsole();
SetConsoleOutputCP(CP_UTF8);
HANDLE consoleHandle = GetStdHandle(STD_OUTPUT_HANDLE);
WriteConsoleA(consoleHandle, "aΕλληνικά\n", 10, NULL, NULL);
WriteConsoleW(consoleHandle, L"wΕλληνικά\n", 10, NULL, NULL);
printf("aΕλληνικά\n");
wprintf(L"wΕλληνικά\n");
现在,问题是根据编码文件被保存为这些作品中的一部分。wprintf 从不工作,但我已经知道原因(损坏的 Microsoft stdout 实现,它只接受窄字符)。然而,我和其他三个人有问题。如果我将文件保存为不带签名 (BOM) 的 UTF-8 并使用 MS Visual C++ 编译器,则只有最后一个 printf 有效。如果我想让 ANSI 版本正常工作,我需要将字符(?)计数增加到 18:
WriteConsoleA(consoleHandle, "aΕλληνικά\n", 18, NULL, NULL);
我认为,WriteConsoleW 不起作用,因为字符串被保存为 UTF-8 字节序列,即使我明确要求将其存储为带有 L 前缀的宽字符(UTF-16),并且实现很可能期望 UTF-16 编码的字符串不是UTF-8。
如果我将它保存在带有 BOM 的 UTF-8 中(应该如此),那么 WriteConsoleW 开始以某种方式工作(???)并且其他一切都停止(我得到 ? 而不是一个字符)。我需要将 WriteConsoleA 中的字符数减少回 10 以保持格式相同(否则我会得到 8 个额外的矩形)。基本上,WTF?
现在,让我们转到 UTF-16(Unicode - 代码页 1200)。仅适用于 WriteConsoleW。WriteConsoleA 中的字符数应为 10 以保持格式精确。
以 UTF-16 Big Endian 模式(Unicode - 代码页 1201)保存不会改变任何内容。再说一次,WTF?存储到文件时不应该反转字符串中的字节顺序吗?
结论是字符串被编译成二进制形式的方式取决于所使用的编码。因此,存储字符串的可移植且独立于编译器的方式是什么?是否有一个预处理器可以在编译之前将一种字符串表示形式转换为另一种表示形式,所以我可以将文件存储在 UTF-8 中,并且只通过将它们包装一些宏来预处理我需要在 UTF-16 中具有的字符串。