【问题标题】:Visual Studio C++ C2022. Too big for character error occurs when trying to print a Unicode characterVisual Studio C++ C2022。尝试打印 Unicode 字符时发生字符错误太大
【发布时间】:2023-03-20 13:53:01
【问题描述】:

当我尝试将 Unicode 字符打印到控制台时。 Visual Studio 给我一个错误。如何解决此问题并让 Visual Studio 打印 Unicode 字符?

#include <iostream>

int main() {
    std::cout << "\x2713";
    return 0;
}

【问题讨论】:

  • \x2713 对于char 来说太大了。你想要L"\x2713"
  • \x2713 太大,无法存储在 char 类型中。试试std::wcout &lt;&lt; L"\2713";
  • @RemyLebeau,你确定吗? G++、Clang 和 MSVC 都认为是one character
  • @ChrisMM 当我点击你的链接时,clang 和 MSVC 都完全出错,gcc 显示一个非常可怕的警告。
  • @MarkRansom,在我的身上,g++ 发出警告,clang/msvc 将其视为错误,但他们都明确表示这是一个字符。

标签: c++ visual-studio unicode


【解决方案1】:

\xNNN(任何正数的十六进制数字)表示单个字节,其值由NNN给出;除非在以L 为前缀的字符串文字或字符文字中,在这种情况下,它表示wchar_t,其值由NNN 给出。

如果您要对 Unicode 代码点进行编码,则语法为 \uNNNN(正好 4 位)或 \UNNNNNNNN(正好 8 位)。请注意,这是代码点,而不是 UTF 表示。

使用uU 表单而不是L 可以避免由于wchar_t 在不同平台上的大小不同而导致的可移植性问题。

要获得明确定义的行为,您可以手动指定字符串文字的编码,例如:

std::cout << u8"\u2713" << std::endl;

它将代码点编码为 UTF-8。当然,您仍然需要一个支持 UTF-8 的终端才能看到有意义的输出。

如果没有编码前缀,则取决于编译器(我认为)以何种方式对代码点进行编码。

见:

【讨论】:

    【解决方案2】:

    很简单,\x2713 对于单个字符来说太大了。如果你想要两个字符,你需要\x27\x13,如果你想要宽字符,那么你需要前缀L,即L"\x2713",然后使用std::wcout而不是std::cout

    注意,来自 C++20 标准(草案)[lex.ccon]/7(强调我的):

    转义符 \ooo 由反斜杠后跟一个、两个或三个八进制数字组成,用于指定所需字符的值。 转义符 \xhhh 由反斜杠后跟 x 后跟一个或多个十六进制数字组成,这些数字用于指定所需字符的值。十六进制序列中的数字位数没有限制。 八进制或十六进制数字序列分别以不是八进制数字或十六进制数字的第一个字符终止。 如果字符文字的值超出为 char(对于没有前缀的字符文字)或 wchar_t(对于以 L 为前缀的字符文字)定义的实现定义范围,则它的值是实现定义的)。

    本质上,编译器可以按照自己的意愿处理该字符; g++ issues a warning, and MSVC (for me) is a compiler error (clang also treats as an error)

    【讨论】:

    • 如果我正确阅读了您的标准剪辑,则无法在数字中间放置十六进制转义符。那真不幸。我一直认为\x 会在 2 位数后停止。
    • @MarkRansom 我认为你是对的 - 从这里 lex.stringlex.ccontimsong-cpp.github.io/cppwp/…
    • 该版本比我的版本更新,仍然表明读取了超过两位数,但使程序格式错误(编译器应该根据该标准对其进行错误处理)。不过我认为该版本适用于 C++23。
    猜你喜欢
    • 1970-01-01
    • 2021-08-02
    • 2013-06-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-12-11
    • 1970-01-01
    相关资源
    最近更新 更多