为什么当转换为 Int32 时,字节的 ASCII 值不同

本文关键字:ASCII 字节 转换 Int32 为什么 | 更新日期: 2023-09-27 17:59:26

我正在创建一个程序,该程序将从文本文档中清除扩展的ASCII字符。我试图了解 C# 如何解释不同的字符集和代码,并注意到一些奇怪之处。

考虑:

namespace ASCIITest
{
    class Program
    {
        static void Main(string[] args)
        {
            string value = "Slide™1½”C4®";
            byte[] asciiValue = Encoding.ASCII.GetBytes(value);   // byte array
            char[] array = value.ToCharArray();                   // char array
            Console.WriteLine("CHAR'tBYTE'tINT32"); 
            for (int i = 0; i < array.Length; i++)
            {
                char  letter     = array[i];
                byte  byteValue  = asciiValue[i];
                Int32 int32Value = array[i];
                 //
                Console.WriteLine("{0}'t{1}'t{2}", letter, byteValue, int32Value);
            }
            Console.ReadLine();
        }
    }
}

程序输出

CHAR    BYTE    INT32
S       83      83
l       108     108
i       105     105
d       100     100
e       101     101
T       63      8482      <- trademark symbol
1       49      49
½       63      189       <- fraction
"       63      8221      <- smartquotes
C       67      67
4       52      52
r       63      174       <- registered trademark symbol

特别是,我试图理解为什么扩展的 ASCII 字符(在第三列右侧添加了我的注释的字符(在转换为 int32 时显示为正确的值,但在转换为byte值时都显示为63。这是怎么回事?

为什么当转换为 Int32 时,字节的 ASCII 值不同

ASCII.GetBytes转换将 ASCII 范围 (0-127( 之外的所有字符替换为问号(代码 63(。

因此,由于您的字符串包含该范围之外的字符,因此您的asciiValue ?而不是所有有趣的符号(如 - 它的Char(Unicode(表示为 8482,这确实超出了 0-127 的范围。

将字符串转换为char数组不会修改字符的值,并且您仍然具有原始的Unicode代码(char本质上是Int16的( - 将其转换为更长的整数类型Int32不会更改值。

以下是将该字符转换为字节/整数的可能:

var value = "™";
var ascii = Encoding.ASCII.GetBytes(value)[0]; // 63(`?`) - outside 0-127 range
var castToByte = (byte)(value[0]); // 34 = 8482 % 256
var Int16 = (Int16)value[0]; // 8482 
var Int32 = (Int16)value[0]; // 8482 

有关详细信息,请参阅ASCIIEncoding Class。

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