【问题标题】:Append multiple hex numbers to QByteArray simultaneously同时将多个十六进制数字附加到 QByteArray
【发布时间】:2015-11-12 20:35:21
【问题描述】:

我有一堆十六进制数字,但我不想这样做

QByteArray ba;
ba.append(0x01);
ba.append(0x02);
ba.append(0x7A);
...

我可以在一行中完成吗?也许与QString 操作有关?

我正在通过串行通信 QExtSerialPort 发送消息,我需要将十六进制命令存储在 QByteArray 中,以便我可以使用 qint64 write(const QByteArray &data)

【问题讨论】:

  • 这些十六进制数字从何而来?请发帖minimal reproducible example
  • ba.append("\x01\x02\x7A")
  • 另外,append 返回一个对自身的引用,所以你也可以链接它:ba.append(0x01).append(0x02).append(0x7A);
  • 数字的表示完全无关。
  • 使用 append 重载,它也需要一个长度,否则是的,它将在第一个 NUL 处停止。

标签: c++ qt hex qbytearray


【解决方案1】:

第一点是:没有十六进制数字这样的东西。数字就是数字。我们在这里谈论整数。不管你说 16、0x10、020 等等,都是同一个数字。 0x10 仅在您以十六进制表示法写出的意义上是“十六进制”。它不会改变数字本身的任何内容,也不会使其成为“十六进制”!它仍然是从零递增 16 次得到的数字。

使用十六进制的唯一原因可能是设备的文档以十六进制提供了命令包。这是一个完全武断的选择。您可以从文档中复制十六进制数字,或者如果对您更有意义,将它们转换为另一个基数。

所以,十六进制表示当然完全取决于您,您不需要明确使用它。但是您确实需要以某种方式使用 C 常量数组 - 它们使事情变得简单且开销低。假设您的命令由三个字节组成,十进制值为 16、33、47。

你可以这样编码:

static const char cmdBuf[] = { 16, 33, 47 };
const auto cmd = QByteArray::fromRawData(cmdBuf, sizeof(cmdBuf));

字节数组cmd是在不复制数据的情况下初始化的,这样既快速又高效。 cmdBuf 必须是静态的,因为它必须与 cmd 或其任何(浅)副本一样存在。

您可以使用字符串文字来初始化数组,对不可打印字符使用十六进制转义符,否则使用可打印字符。

static const char cmdBuf[] = "\x10!/";
const auto cmd = QByteArray::fromRawData(cmdBuf, sizeof(cmdBuf)-1);

sizeof(...)-1 的原因是 cmdBuf 有 4 个字节长 - 字符串文字以您并不真正需要的终止零结尾。

如果您希望对所有字节使用十六进制表示,则可以

static const char cmdBuf[] = "\x10\x21\x2F";
const auto cmd = QByteArray::fromRawData(cmdBuf, sizeof(cmdBuf)-1);
// or
static const char cmdBuf[] = { 0x10, 0x21, 0x2F };
const auto cmd = QByteArray::fromRawData(cmdBuf, sizeof(cmdBuf));

当然你也可以使用八进制:

static const char cmdBuf[] = "\020\041\057";
const auto cmd = QByteArray::fromRawData(cmdBuf, sizeof(cmdBuf)-1);
// or
static const char cmdBuf[] = { 020, 041, 057 };
const auto cmd = QByteArray::fromRawData(cmdBuf, sizeof(cmdBuf));

或者它们的任意组合!

static const char cmdBuf[] = "\020\x21/";
const auto cmd = QByteArray::fromRawData(cmdBuf, sizeof(cmdBuf)-1);
//or
static const char cmdBuf[] = { 16, 0x21, 057 };
const auto cmd = QByteArray::fromRawData(cmdBuf, sizeof(cmdBuf));

在字符串文字中,是否将其全部编码为十六进制/八进制转义符或使用可打印字符取决于您,这是样式问题。如果您的命令中的值不具有可打印字符的含义,那么字符串文字或数组初始值设定项中的数字(十六进制或八进制)编码可能会更好。

在八进制和十六进制之间进行选择时,请遵循命令字节的结构或您自己的偏好。如果字节的结构以某种方式分解为 2+3+3 位组,那么八进制是使其易于阅读的好方法。否则,使用十六进制或十进制。关键在于使代码更易于阅读 - 机器不在乎,无论您采用哪种方式,二进制输出都是相同的。

【讨论】:

  • “cmdBuf 必须是静态的” - 您能否说明这是在标头 (.h) 还是源 (.cpp) 中完成的?
  • 它通常在发出命令的代码中,所以在函数/方法中。现在,该函数/方法的定义是在.h 文件还是.cpp 文件中取决于其他因素。
猜你喜欢
  • 2014-08-24
  • 2023-03-28
  • 2013-10-16
  • 2018-02-14
  • 2019-01-30
  • 1970-01-01
  • 1970-01-01
  • 2014-07-14
  • 2016-08-04
相关资源
最近更新 更多