【问题标题】:Writing unicode(?) character directly from source code to WriteConsoleOutput将 unicode(?) 字符直接从源代码写入 WriteConsoleOutput
【发布时间】:2016-10-06 15:40:12
【问题描述】:

我正在尝试使用 WinApi 中的 WriteConsoleOutput 将字符写入命令提示符窗口缓冲区。问题是,我真的很希望能够按原样将诸如 之类的字符直接写入源代码,而不是使用诸如'\uFFFF''0xFF' 之类的某种编码/符号,因为我不太了解它们(代码页/字符集/等之间的差异)

下面的代码展示了我的问题的最简单形式。运行此代码不会将 打印到命令提示符窗口中,而是会打印一个问号 (?)。

#include <Windows.h>

int main()
{
    HANDLE h = GetStdHandle(STD_OUTPUT_HANDLE);
    CHAR_INFO c[1] = {0};
    COORD cS = {1, 1};
    COORD cH = {0, 0};
    SMALL_RECT sr = {0, 0, 0, 0};

    c[0].Attributes = FOREGROUND_INTENSITY;
    c[0].Char.UnicodeChar = '☺';
    WriteConsoleOutput(h, c, cS, cH, &sr);
    Sleep(5000);
    return 0;
}

无论安装/使用何种语言,我的代码都必须在所有 Windows 版本之间以相同的方式显示输出。所以据我所知(诚然,这绝对是最小的),我需要设置一个特定的代码页(希望任何语言 Windows 的命令提示符都支持该代码页)。

我试过了:
• 从使用CHAR_INFO.UnicodeChar 更改为CHAR_INFO.AsciiChar
• 摆弄SetConsoleCPSetConsoleOutputCP 函数,但我不知道如何利用它们来帮助我解决这个问题。
• 将Visual Studio -> 项目-> 项目属性.. -> 字符集 设置更改为每个可能的值。
• 除上述设置外,还专门使用WriteConsoleOutputAWriteConsoleOutputW
• 将源代码文件编码更改为带有(/out) 签名的UTF-8。


在我的项目中,我以编程方式将命令提示符字体设置为 8x8 终端,据我所知,它不支持实际的 unicode 字符。可用字符显示为here。这些字符确实包括“☺”,所以我不完全确定我的问题是关于 unicode。我已经不知道了。请帮忙。

【问题讨论】:

  • 你必须使用 c[0].Char.UnicodeChar = L'☺';并确保编译器理解您的源代码,使用文件 > 高级保存选项 > 选择“Unicode (UTF-8 with signature) - Codepage 65001”。现在发出的 BOM 足以让编译器知道源代码是 utf8 编码的。
  • @hans-passant 这给了我一个:(冒号)而不是笑脸。即使编码保存为 UTF-8。
  • 字符是U+263A, 3A == ':'。 L 很重要。
  • @user6003859 您的源代码文件是否有 UTF-8 BOM 标记?编译器的最新更新支持指定源代码编码的替代方法 - 请参阅New Options for Managing Character Sets in the Microsoft C/C++ Compiler。确保您设置c[0].Char.UnicodeChar 并调用WriteConsoleOutputW
  • @HansPassant @IanAbbott 啊!最后!使用L 宏、UnicodeChar、文件上的 UTF-8 编码和WriteConsoleOutputW() 终于奏效了。我以为我已经尝试了这些选择的所有变化。非常感谢!我不能投票给 cmets,所以无论谁添加了上述详细信息的答案,都会得到“接受”的东西。再次感谢您。

标签: c++ c arrays string windows


【解决方案1】:

C 源代码只能是 ascii。如果您在 C 源文件中嵌入非 ascii 字符,IDE 可能会以看似正确的格式显示它们,但编译器很可能会以不同的方式处理它们,并且您传递给它们的可执行函数仍然可以以不同的方式处理它们。它只是不便携或不可靠。但是您可以使用转义序列 \x 在 C 字符串中嵌入任意字节。

UTF-8 适合内部使用,但 Windows API 尚不支持它,因此您需要转换为 Windows 16 位字符(接近但不完全是 UTF-16),以显示扩展字符。但是,您必须确保调用的是 Windows API 的宽字符版本。大多数采用字符串的 Windows API 函数都有 A 和 W 版本(ascii 和 Wide),以实现二进制向后兼容。如果您在 IDE 中查询标识符(转到定义等),您应该会看到您拥有的版本。

【讨论】:

    猜你喜欢
    • 2020-05-28
    • 1970-01-01
    • 1970-01-01
    • 2011-03-17
    • 2010-10-18
    • 2019-09-04
    • 1970-01-01
    • 2013-10-17
    • 1970-01-01
    相关资源
    最近更新 更多