2

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

据我所知,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 被报告为四个而不是三个。

我在这里错过了什么吗?

4

2 回答 2

0

MSDN 说该char类型可以表示 Unicode 16 位字符(因此只有字符形式的 BMP)。

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

于 2013-05-10T16:08:15.750 回答
-1

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

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

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

这篇MSDN 文章介绍了如何使用\uxxxx序列来指定所需的 Unicode 字符代码。此博客条目列出了所有各种 C# 转义序列 - 我包括它的原因是因为它提到使用 \xnnn - 避免使用这种格式:它是可变长度版本,\u它可能会在某些情况下导致问题(不在你的, 尽管)。

MSDN 文章指出了为什么字符分配不好:所讨论字符的代码点是 > FFFF,它超出了 char 类型的范围。

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

于 2013-05-10T15:54:24.790 回答