为什么值为128的char是一个空字符串而不是欧元符号€?

3
根据ASCII表,128的值是。然而,在C#中执行以下代码并不能返回欧元符号。
char expectedEuro = Convert.ToChar(128);

尝试将字符转换为Char时,始终会导致OverflowException,因为它对于无符号字节来说太大了。
Convert.ToByte(`€`);

我们从另一个系统编码输出值为 128 时,会得到 字符,但在 C# 中却输出为空字符,这给我们带来了麻烦。

这是为什么?我该怎么解决?


1
Convert.ToChar(128) // 返回 € Convert.ToByte(Convert.ToChar(128)) // 返回 128 我不明白你的问题是什么? - dav_i
2
感谢C#、.NET以及整个IT行业已经转向Unicode编码,这一实践早在多年前就已经开始了。我已经老到能够记得上世纪70年代和80年代时由于不兼容的字符集、ASCII、EBCDIC和代码页等问题而带来的无休止的疯狂问题。 - RenniePet
ASCII库或系统很少见。当你想到“ASCII”时,停下来确定实际的字符集和编码。对于.NET库,它几乎总是Unicode/UTF-16(以机器字节顺序)或Unicode/UTF-8用于文件流。因此,您必须确定其他系统使用的字符集/编码,然后使用Encoding类进行正确的转换。 - Tom Blodget
2个回答

11

C#/.NET使用Unicode字符集,因此符号对应的是8364

你可以通过以下方式进行检查:

int val = (int)'€'; // val will be 8364
这也意味着您不能将大多数字符表示为一个字节,因为它们需要2个字节。

如果您想使用扩展ASCII表,可以使用Encoding.Default:
var valStr = Encoding.Default.GetString(new byte[] { 128 }); // valStr = €
var valByte = Encoding.Default.GetBytes("€"); // valByte[0] = 128

Encoding.Default 使用当前 ANSI 代码页(请参见 Joe 的回答或 Jeppe 的评论以选择特定的代码页),而Encoding.ASCII 使用 7 位 ASCII 表,因此在 ASCII 中没有 128


1
这是正确的解释。在Unicode下,十进制128或U+0080是“PAD - 填充字符”C1控制字符,请参见Latin-1 Supplement补充:请参见货币符号块中的欧元符号。 - Jeppe Stig Nielsen
此外,提问者链接的页面实际上给出了Windows 1252代码页,它不是Unicode。在.NET中不应使用Windows-1252特定的代码点。 - Jeppe Stig Nielsen
5
Encoding.Default 不一定是 CP1252,所以如果要在国际上使用,您应该明确指定您想要的编码。 - Joe
3
警告:使用 Encoding.Default 的技巧会返回操作系统本地的代码页。对于 Windows 中的“西欧语言”版本,它将是 Windows-1252,但如果该代码在保加利亚语或希腊语版本的 Windows 上运行,则会给出另一个代码页。因此更安全的做法是使用 Encoding.GetEncoding("Windows-1252") - Jeppe Stig Nielsen
@Joe:谢谢,我刚把它添加到答案中了。 - Christoph Fink
@Joe 啊,你先写了。不过我还是会留下我的评论,因为它提供了要使用的具体语法。 - Jeppe Stig Nielsen

4

ASCII是一种7位编码:你提供的表格描述了欧元符号的一种特定编码。

如果您想要对欧元符号进行编码,以便其他系统可以识别它,您可能需要使用适当的编码方式进行编码,例如:

var v = System.Text.Encoding.GetEncoding(1252).GetBytes("€");
Console.WriteLine(Convert.ToByte(v[0])); // = 128

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接