我正在尝试确定字符编码对我正在计划的软件系统的影响,我在测试时发现了一些奇怪的东西。
据我所知,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报告为四个而不是三个。
我在这里错过了什么吗?
答案 0 :(得分:0)
您的源文件可能无法保存为UTF-8(在源代码中使用特殊字符时建议使用),因此编译器实际上可能会看到一个混淆它的字节序列。您可以通过在十六进制编辑器中打开源文件来验证 - 您将看到的字符代替您的角色可能会有所不同。
如果它尚未打开,您可以在工具 - >选项 - > Visual Studio中的文档(我使用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
所有这些都包含在对这个答案的评论中,所以我刚刚将相关信息带入了这个答案,现在接受了。
答案 1 :(得分:0)
MSDN says that the char
type can represent Unicode 16-bit character(因此只有字符形式为BMP)。
如果使用BMP外的字符(UTF-16:补充对 - 2x16位)编译器将其视为两个字符。