【问题标题】:convert a Non-displayable ASCII array to decimal将不可显示的 ASCII 数组转换为十进制
【发布时间】:2016-07-27 11:41:27
【问题描述】:

我从我的串口收到一个字节数组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 位 HEX 值的结果是错误的,等于 63(0x3F) 有什么解决办法吗?

【问题讨论】:

  • 从串口读取字节而不是字符串。或者尝试使用Encoding.Default 而不是Encoding.ASCII
  • @Alexander Petrov 对Encoding.default 的结果相似
  • 因为串口的编码还是Encoding.ASCII。您还需要更改sp.Encoding(最好在创建SerialPort 实例之后立即更改)。 ASCII 是 7 位字符集,不能表示大于 127 的值。0xA0 大于 127,因此它被编码为 63 - ?
  • @Luaan 我按照您的建议将我的sp.Encoding 更改为默认值并且它有效。非常感谢。
  • 这很可能是解决该问题的一种非常糟糕的方法,但如果这是你想要的...... :)

标签: c# ascii .net-cf-3.5


【解决方案1】:

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 是一个十进制数。您可能想改用byteint

【讨论】:

  • 帮助 OP 陷入成功的深渊,buffer 变量应该始终是类的一个字段,而 Read() 的第二个参数应该始终是一个变量计算缓冲区中的字节数。
【解决方案2】:

您不需要将字节转换为十进制:

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

【讨论】:

  • @Ehsan.Da 我已经编辑了我的答案。这对你有用吗?
  • 谢谢,我马上查了。但是没有用。我想也许我收到的字符串不是 8 位 HEX 字节的正确字符串
猜你喜欢
  • 1970-01-01
  • 2019-10-31
  • 1970-01-01
  • 2019-02-03
  • 1970-01-01
  • 2017-04-16
  • 2010-12-03
  • 1970-01-01
  • 2022-01-09
相关资源
最近更新 更多