2013-04-12 249 views
2

此C#代码...ASCIIEncoding.ASCII.GetBytes()返回意外值

string s = "\u00C0"; 
byte[] bytes = ASCIIEncoding.ASCII.GetBytes(s); 
Trace.WriteLine(BitConverter.ToString(bytes)); 

产生以下输出:

3F 

为什么输出不C0?

+2

您可能正在寻找'Encoding.GetEncoding( “ISO-8859-1”) .GetBytes(多个)'。这是[只给出正好代码点值的字节值的编码](http://stackoverflow.com/a/15938015/995876)。 – Esailija

+0

我想知道,为什么你需要ASCIIEncoding? UTF8Encoding有什么问题? –

回答

4

因为\u00c0不是ASCII码(0-127范围)。结果它被编码,就好像它是问号 - ?(0x3F)。

ASCIIEncoding

参见MSDN文章:

ASCIIEncoding对应于20127. Windows的代码页由于ASCII是一个7位编码,ASCII字符被限制到最低128 Unicode字符,从U + 0000到U + 007F。如果使用由Encoding.ASCII属性或ASCIIEncoding构造函数返回的默认编码器,则在执行编码操作之前,该范围之外的字符将替换为问号(?)。

1

第一步:您将unicode字符串转换为字符串,然后将其转换为ASCII(但是它是unicode)。然后,您正试图使用​​unicode转换器将其转换回来。

下面的例子做一切可能使我的反应更加清晰:

static void Main(string[] args) 
    { 
     string s = "\u00C0"; 
     Console.WriteLine(s); 
     byte[] bytes = ASCIIEncoding.ASCII.GetBytes(s); 
     Console.WriteLine(BitConverter.ToString(bytes)); 
     Console.WriteLine(ASCIIEncoding.ASCII.GetString(bytes)); 

     Console.WriteLine("Again"); 
     bytes = Encoding.UTF8.GetBytes(s); 
     Console.WriteLine(BitConverter.ToString(bytes)); 
     Console.WriteLine(Encoding.UTF8.GetString(bytes)); 

     Console.ReadLine(); 
    } 

,输出是:

A 
3F 
? 
Again 
C3-80 
A 

顺便说一句BitConverter.GetBytes的定义是:

将指定数组的 字节的每个元素的数值转换为其等效的六进制十进制串表示。

+0

'BitConverter.ToString(bytes)'是将字节数组转换为空格分隔的十六进制字符串的便捷方式。它在OP的代码中用作简单的方式输出十六进制字节数组的值。 – Verax

3

看来你想要一个代表一串Unicode字符的字节序列。显然,这些字节将取决于编码。由于您预计C0是其中一个字节,因此会缩小选项的范围。这里是utf16le应按,这当然是两个字节,因为\u00c0完全代表一个字符BMP

string s = "\u00C0"; 
byte[] bytes = Encoding.Unicode.GetBytes(s); 
Trace.WriteLine(BitConverter.ToString(bytes)); 

你应该阅读The Absolute Minimum Every Software Developer Absolutely, Positively Must Know About Unicode and Character Sets (No Excuses!) by Joel Spolsky