【问题标题】:Unicode escape sequences vs hexadecimal valuesUnicode 转义序列与十六进制值
【发布时间】:2018-01-22 19:17:01
【问题描述】:

为了在我的程序中编码 Unicode/UTF-8 字符,我一直在使用 \uXXXX 转义序列,例如:

wchar_t superscript_4 = L'\u2074';  // U+2074 SUPERSCRIPT 4 '⁴'
wchar_t subscript_4   = L'\u2084';  // U+2084 SUBSCRIPT 4 '₄'

但是,使用十六进制应该可以正常工作,因为 Unicode 是用十六进制编码的。

wchar_t superscript_4 = 0x2074;
wchar_t subscript_4   = 0x2084;

第二个例子会正确编码字符吗?我会遇到宽字符问题、分段错误或错误存储的字符值吗?如果是这样,为什么?如果不是,为什么?

【问题讨论】:

  • 据我所知,第一个示例定义了一个值大于 CHAR_MAX 的字符文字。这本身就很糟糕......
  • 你试过L'\u2074'而不是'\u2074'吗?
  • @rubenvb 哎呀,打错了。已修复(根据 Keine 的评论)。
  • @PeterJ 多字符字符由实现定义和字节序相关
  • @KeineLust 它们可能依赖于字节序,但它们是实现定义的,并且实现可以将它们定义为使用特定的字节序,独立于执行中使用的任何内容。

标签: c unicode utf-8 hex widechar


【解决方案1】:

可以使用十六进制常量初始化它们,但您也可以使用数字常量初始化普通的chars,例如char c = 67;。它的工作方式相同;它分配任何charwchar_t 具有int 的值。在您给出的示例中,并假设 Unicode 执行环境(不太有保证,但很有可能)它是下标或上标 4;在我的示例中,它是大写字母 C

In particular,对于常规的chars,技术上像'C' 这样的字符常量具有int 类型,您通常将int 值分配给chars。对于wchar_ts,常量确实有wchar_t 类型,整数值与调用mbtowc 得到的值相同。因此,假设您在 Unicode 环境中工作,十六进制常量等同于 Unicode 转义。

不过,通常你不想这样做;使用字符文字可以更清楚地说明您的意图。如果您在源代码中使用非 ASCII 字符,则尤其如此,在这种情况下,您可以将代码设为

wchar_t superscript_4 = L'⁴'
wchar_t subscript_4   = L'₄'

还要注意,对于许多用途,最好使用char16_tchar32_t,因为wchar_t 在不同平台上可以有不同的宽度;在您特别需要切换到其他东西之前,只使用 UTF-8 也可能更简洁。

【讨论】:

  • 那么用十六进制常量初始化它们做同样的事情吗? (我看了你的回答,我同意第二句话,我只是好奇。)
  • @MDXF 确实如此,假设执行环境是 Unicode。理论上,执行环境可以使用一些多字节非 Unicode 字符集,在这种情况下,Unicode 转义仍然可以工作(如果执行字符集具有正确的字符),但十六进制常量不会;实际上,执行环境将是 Unicode,这不是问题。
猜你喜欢
  • 1970-01-01
  • 2020-02-06
  • 2018-08-16
  • 2016-08-15
  • 2018-07-26
  • 2021-04-30
  • 1970-01-01
  • 2016-09-04
  • 2019-01-27
相关资源
最近更新 更多