【问题标题】:Unicode SMP "character" in C# char [duplicate]C# char 中的 Unicode SMP“字符”[重复]
【发布时间】:2013-05-05 08:43:21
【问题描述】:

我正在尝试确定字符编码对我正在计划的软件系统的影响,但在进行测试时发现了一些奇怪的东西。

据我所知,C# 内部使用 UTF-16,(据我所知)它包含使用两个 16 位字段的每个 Unicode 代码点。所以我想制作一些字符文字并故意选择????和얤,因为前者来自SMP平面,后者来自BMP平面。结果是:

char ch1 = '얤'; // No problem
char ch2 = '????'; // Compilation error "Too many characters in character literal"

发生了什么事?

这个问题的一个推论是,如果我有字符串“얤????얤”,它会在 MessageBox 中正确显示,但是当我使用 ToCharArray 将其转换为 char[] 时,我会得到一个包含四个元素的数组而不是三个。此外,String.Length 报告为四个而不是三个。

我错过了什么吗?

【问题讨论】:

  • 可能是保存复杂字符????作为 Unicode 代码点,通常长度为两个字符。
  • @RaymondChen 敏锐的眼光...我尝试了几次不同的搜索,但没有发现任何相关内容!
  • 我能以某种方式关闭这个问题作为重复吗?

标签: c# character-encoding astral-plane


【解决方案1】:

您的源文件可能没有以 UTF-8 格式保存(在源文件中使用特殊字符时建议这样做),因此编译器实际上可能会看到一个混淆它的字节序列。您可以通过在十六进制编辑器中打开源文件来验证这一点 - 您将看到的代替角色的字节可能会有所不同。

如果它尚未打开,您可以在 Visual Studio 中的 Tools->Options->Documents 中打开该设置(我使用 2008) - 选项是 Save documents as Unicode when data cannot be saved in codepage

通常,最好使用字符序列来指定特殊字符。

MSDN article 描述了如何使用\uxxxx 序列来指定所需的Unicode 字符代码。这个blog entry 列出了所有各种 C# 转义序列 - 我之所以包含它是因为它提到使用 \xnnn - 避免使用这种格式:它是 \u 的可变长度版本,在某些情况下可能会导致问题(不过,不在你的)。

MSDN article 指出了字符分配不好的原因:相关字符的代码点是 > FFFF,超出了 char 类型的范围。

至于问题的字符串部分,答案是SMP字符表示为两个char值。 This SO question 包含一些显示如何从字符串中获取代码点的代码,它涉及使用 StringInfo.GetTextElementEnumerator

【讨论】:

  • 答案实际上在您引用的 MSDN 文章中...... ? 的代码点是 1D6C03 并且文章指出不支持 10FFFF 以上的代码点。谢谢!
  • 严格来说,我之前的评论是不正确的,MSDN 文章指出“在字符文字中不允许使用 U+10000 到 U+10FFFF 范围内的 Unicode 字符,并且使用 Unicode 代理对表示一个字符串文字”,但它接着说在字符串中不支持超过 10FFFF 的 Unicode 字符。只是为了澄清...... char 文字无效,因为代码点高于 FFFF,字符串文字无效,因为代码点高于 10FFFF
  • 我不明白为什么我的带有>10FFFF 代码点的字符串在MessageBox 中正确显示...
  • @Paul 这个链接可能会回答这个问题(我以前不知道这个限制):stackoverflow.com/questions/8369772/…
  • 实际上,到目前为止的答案是我很烂...我错误地创建了代码点,它不是 1D6C03 而是 1D6C3...我在我的 3 之前用了一个 0愚蠢。所以 1D6C3 FFFF 所以它在字符文字中不好,必须在字符串中。
【解决方案2】:

MSDN says that the char type can represent Unicode 16-bit character(因此只有字符形式的 BMP)。

如果您使用 BMP 之外的字符(在 UTF-16 中:补充对 - 2x16 位),编译器会将其视为两个字符。

【讨论】:

    猜你喜欢
    • 2012-08-16
    • 2017-01-29
    • 1970-01-01
    • 1970-01-01
    • 2022-01-10
    • 2013-07-12
    • 2012-01-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多