将不可显示的 ASCII 数组转换为十进制
convert a Non-displayable ASCII array to decimal
我从我的串行端口接收到一个字节数组 serial_port[4] {0x00, 0xA0, 0x05, 0xB1}
,如下所示:
string rec_data += sp.ReadExisting();
我需要使用以下方法将此字符串转换为十进制值:
byte[] Temp = Encoding.ASCII.GetBytes(rec_data);
decimal r0 = Convert.ToDecimal(Temp[0]);
decimal r1 = Convert.ToDecimal(Temp[1]);
decimal r2 = Convert.ToDecimal(Temp[2]);
decimal r3 = Convert.ToDecimal(Temp[3]);
但结果值不是我想要的:
r0 = 0
r1 = 63
r2 = 5
r3 = 63
如您所见,8 位十六进制值的结果是错误的,等于 63(0x3F)
有什么解决的建议吗?
您不需要将字节转换为十进制:
byte[] Temp = Encoding.ASCII.GetBytes(rec_data);
decimal r0 = Temp[0];
decimal r1 = Temp[1];
decimal r2 = Temp[2];
decimal r3 = Temp[3];
int 的值:
r0 - 0
r1 - 160
r2 - 5
r3 - 177
ASCII 是 7 位字符集。 ASCII 中没有 0xA0
这样的东西。 63
恰好是 ASCII 中的 ?
- 当给定字符集中无法表示特定值时使用的字符。
当数据不是字符时不要将数据作为字符数据读取。不要使用假定字符数据的 ReadExisting
。相反,您需要这样的东西:
var buffer = new byte[256];
var bytesRead = sp.Read(buffer, 0, buffer.Length)
// buffer[0..bytesRead-1] now contains all the data read from the port
当然,您可能需要多次读取才能获得整个消息,或者您可能希望一次只读取有限数量的字节,具体取决于您的协议的工作方式。
为您处理此问题的简单 SerialPort
包装器可能如下所示:
class MySerialPort
{
private readonly SerialPort _port;
public MySerialPort(SerialPort port)
{
this._port = port;
}
public byte[] ReadBytes(int amount)
{
var data = new byte[amount];
var offset = 0;
while (amount > 0)
{
var bytesRead = _port.Read(data, offset, amount);
offset += bytesRead;
amount -= bytesRead;
}
return data;
}
}
根据您实际尝试做的事情,您可能想添加一些缓冲或不添加缓冲,但这对于串行端口上常用的协议类型来说效果很好。如果这就是您真正需要的,您可以简单地将 ReadBytes
作为 SerialPort
.
上的扩展方法
此外,decimal
是十进制数。您可能想改用 byte
或 int
。
我从我的串行端口接收到一个字节数组 serial_port[4] {0x00, 0xA0, 0x05, 0xB1}
,如下所示:
string rec_data += sp.ReadExisting();
我需要使用以下方法将此字符串转换为十进制值:
byte[] Temp = Encoding.ASCII.GetBytes(rec_data);
decimal r0 = Convert.ToDecimal(Temp[0]);
decimal r1 = Convert.ToDecimal(Temp[1]);
decimal r2 = Convert.ToDecimal(Temp[2]);
decimal r3 = Convert.ToDecimal(Temp[3]);
但结果值不是我想要的:
r0 = 0
r1 = 63
r2 = 5
r3 = 63
如您所见,8 位十六进制值的结果是错误的,等于 63(0x3F) 有什么解决的建议吗?
您不需要将字节转换为十进制:
byte[] Temp = Encoding.ASCII.GetBytes(rec_data);
decimal r0 = Temp[0];
decimal r1 = Temp[1];
decimal r2 = Temp[2];
decimal r3 = Temp[3];
int 的值:
r0 - 0
r1 - 160
r2 - 5
r3 - 177
ASCII 是 7 位字符集。 ASCII 中没有 0xA0
这样的东西。 63
恰好是 ASCII 中的 ?
- 当给定字符集中无法表示特定值时使用的字符。
当数据不是字符时不要将数据作为字符数据读取。不要使用假定字符数据的 ReadExisting
。相反,您需要这样的东西:
var buffer = new byte[256];
var bytesRead = sp.Read(buffer, 0, buffer.Length)
// buffer[0..bytesRead-1] now contains all the data read from the port
当然,您可能需要多次读取才能获得整个消息,或者您可能希望一次只读取有限数量的字节,具体取决于您的协议的工作方式。
为您处理此问题的简单 SerialPort
包装器可能如下所示:
class MySerialPort
{
private readonly SerialPort _port;
public MySerialPort(SerialPort port)
{
this._port = port;
}
public byte[] ReadBytes(int amount)
{
var data = new byte[amount];
var offset = 0;
while (amount > 0)
{
var bytesRead = _port.Read(data, offset, amount);
offset += bytesRead;
amount -= bytesRead;
}
return data;
}
}
根据您实际尝试做的事情,您可能想添加一些缓冲或不添加缓冲,但这对于串行端口上常用的协议类型来说效果很好。如果这就是您真正需要的,您可以简单地将 ReadBytes
作为 SerialPort
.
此外,decimal
是十进制数。您可能想改用 byte
或 int
。