【问题标题】:Encoding.GetEncoding(437).GetString() bug?Encoding.GetEncoding(437).GetString() 错误?
【发布时间】:2011-10-22 11:41:20
【问题描述】:

我有以下测试程序

char c = '§';
Debug.WriteLine("c: " + (int)c);

byte b = Encoding.GetEncoding(437).GetBytes("§")[0];
Debug.WriteLine("b: " + b);

char c1 = Encoding.GetEncoding(437).GetString(new byte[] { 21 })[0];
Debug.WriteLine("c1: " + (int)c1);

这会产生以下结果:

c: 167
b: 21
c1: 21

我可以看到 here GetBytes 工作正常
Unicode 中的 167 => CP437 中的 21
但 GetString 不工作
CP437 中的 21 => Unicode 中的 21

这是一个错误还是我的错误?

【问题讨论】:

  • 一个长镜头,但GetBytes 和GetString 都返回一个元素的数组吗?
  • 这可能是因为 CP437 中不能写入 167,所以它映射到 CP437 中的占位符 21(可能是 ?)。占位符映射回 unicode 中的占位符,也就是 21。
  • @Dani:你确定吗?该字符确实存在并且在 CP437 中有效,它应该使用一个字节来表示它。它在 Unicode 中可能超过一个字节,但在 437 中没有。检查链接的 wiki 中的 char 21,即那个字符。
  • @Kieren Johnstone - 是 GetBytes(...).Length = 1 和 GetString(...).Length = 1
  • 您能否再次出于兴趣尝试显示/打印从GetString 返回的字符串?我不知道这些方法的内部工作原理,但我同意这看起来很奇怪。

标签: c# .net .net-3.5 character-encoding


【解决方案1】:

CP437 对于 0-31 范围内的字符不是“双向”的。如您链接的维基百科页面所述:

对于许多用途,0 到 31 范围内的代码和代码 127 将 不产生这些符号。其中一些(或全部)将被解释 作为 ASCII 控制字符。

将 Unicode 字符映射到此范围内受支持的 CP437 字符是可行的,但反之则不行。例如,以字节 13 和 10 表示的字符:如果您将它们放在 CP437 字符串中,您实际上希望保留回车符和换行符,而不是转换为项目符号和音符。这种行为是正常的:这不是错误。

【讨论】:

  • 你可以称之为缩小转化
  • 天啊,讨厌被这样的 MS 设计决定打败。现在我需要查找/编写双向 CP437 编码。 :-(
  • @SeeR:WinAPI 函数MultiByteToWideChar 通过它的MB_USEGLYPHCHARS 标志支持这一点:“使用字形字符而不是控制字符。”。但请注意,如果您的文本有 CRLF,它们将返回为“♪◙” - 因为您的文件不再有任何 CR+LF,而是有 Eighth Note+Inverse White Circle
【解决方案2】:

.net 支持两个不同的字符,这两个字符(通常)都呈现为§:

char c1 = (char)21;
char c2 = (char)167;

Console.WriteLine(c1 == c2);  // prints false
Console.WriteLine(c1);        // prints §
Console.WriteLine(c2);        // prints §

字符 21 是一个特殊的控制字符,在文本模式下输出时呈现为§。

CP437 允许将 21 解释为控制字符或文字 §。显然,GetString 选择将其解释为控制字符(这是一个完全有效的选项),因此,将其映射到 Unicode 控制字符 21 而不是 Unicode 文字 §。

【讨论】:

  • 在我的机器上Console.WriteLine(c1) 打印EMPTY 和Console.WriteLine(c2); 打印§
  • 我想是的,我使用的是 windows xp sp3 和 Visual Studio 2010。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-03-26
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多