qt-通信协议基础-QStirng转QByteArray-与字节序互动

提问

QStirng转QByteArray是大端字节序,还是小端字节序?

分析

在 Qt 中,QString 转换为 QByteArray 的字节序(大端或小端)取决于编码方式,而不是直接由 QString 或 QByteArray 本身决定。

  • QString 和 QByteArray 的本质
    • QString 是 Unicode 字符串(默认 UTF-16 编码,内部使用 QChar,即 16 位无符号整数)。
    • QByteArray 是原始字节数组,不包含任何内置的字节序信息。它的字节顺序由编码转换时的规则决定。
  • QString 转 QByteArray 的字节序
    • 默认行为:
      当使用 QString::toUtf8()、toLatin1() 或 toLocal8Bit() 等方法时,转换的是字符的编码(如 UTF-8、ISO-8859-1 等),不涉及多字节数值的字节序问题。
      原因:这些编码是按字节存储的,每个字符的字节顺序是固定的(例如 UTF-8 是变长编码,无字节序问题;Latin1 是单字节编码)。
    • UTF-16 编码的字节序:
      如果显式使用 QString::toUtf16(),返回的 QByteArray 会包含 UTF-16 编码的字节流,此时字节序由系统字节序或显式指定的字节序标记(BOM)决定:
    • 无 BOM:默认使用系统字节序(通过 QSysInfo::ByteOrder 查询,可能是 QSysInfo::BigEndian 或 QSysInfo::LittleEndian)。
    • 有 BOM:如果传入 QString::toUtf16() 的参数为 withBom = true,会在开头添加 2 字节的 BOM(0xFEFF 表示大端序,0xFFFE 表示小端序)。
cpp 复制代码
QString str = "Hello";

// 默认系统字节序(无 BOM)
QByteArray utf16Default = str.toUtf16(); // 字节序取决于系统

// 显式添加 BOM(根据 BOM 决定字节序)
QByteArray utf16WithBom = str.toUtf16(true); // 包含 BOM,可明确字节序
  • 如何控制字节序?
    强制小端序或大端序:如果需要明确指定字节序,可以手动处理 QString 的 UTF-16 数据。
cpp 复制代码
QString str = "Hello";

// 转换为 UTF-16 小端序(无 BOM)
QByteArray utf16LE;
const QChar *chars = str.unicode();
for (int i = 0; i < str.length(); ++i) {
    quint16 ch = chars[i];
    // 小端序:低字节在前
    utf16LE.append(static_cast<char>(ch & 0xFF));       // 低字节
    utf16LE.append(static_cast<char>((ch >> 8) & 0xFF)); // 高字节
}

// 转换为 UTF-16 大端序(无 BOM)
QByteArray utf16BE;
for (int i = 0; i < str.length(); ++i) {
    quint16 ch = chars[i];
    // 大端序:高字节在前
    utf16BE.append(static_cast<char>((ch >> 8) & 0xFF)); // 高字节
    utf16BE.append(static_cast<char>(ch & 0xFF));       // 低字节
}
  • 使用 QDataStream 控制字节序:如果需要将 QString 序列化为二进制数据并控制字节序,可以结合 QDataStream。
cpp 复制代码
QString str = "Hello";
QByteArray data;
QDataStream stream(&data, QIODevice::WriteOnly);

// 设置字节序(小端或大端)
stream.setByteOrder(QDataStream::LittleEndian); // 或 BigEndian

// 写入 QString(会以 UTF-16 格式存储,受 ByteOrder 影响)
stream << str;
  • 总结
    • 常见编码(UTF-8、Latin1):QString 转 QByteArray 无字节序问题,因为它们是按字节存储的。
    • UTF-16 编码:
    • 默认使用系统字节序(无 BOM)。
    • 通过 toUtf16(true) 可添加 BOM 明确字节序。
    • 手动处理或 QDataStream 可强制指定字节序。
    • 关键点:字节序仅在多字节数值(如 UTF-16 的 QChar)转换时需要关注,单字节编码(如 UTF-8)无需考虑。

示例代码(验证字节序)

cpp 复制代码
#include <QCoreApplication>
#include <QDebug>
#include <QString>
#include <QSysInfo>

int main(int argc, char *argv[]) {
    QCoreApplication a(argc, argv);

    QString str = "A"; // Unicode 字符 'A' 的 UTF-16 编码为 0x0041

    // 默认 UTF-16 转换(无 BOM)
    QByteArray utf16Default = str.toUtf16();
    qDebug() << "Default UTF-16 (no BOM):" << utf16Default.toHex();
    // 系统是小端序时输出: "4100"(低字节在前)
    // 系统是大端序时输出: "0041"(高字节在前)

    // 带 BOM 的 UTF-16
    QByteArray utf16WithBom = str.toUtf16(true);
    qDebug() << "UTF-16 with BOM:" << utf16WithBom.toHex();
    // 小端序系统输出: "fffe4100"(BOM=FFFE,数据=4100)
    // 大端序系统输出: "feff0041"(BOM=FEFF,数据=0041)

    return a.exec();
}

通过运行此代码,可以观察不同系统下的字节序差异。

互动

qt-通信协议基础-固定长度-小端字节序补0x00指导

相关推荐
曹轲恒5 小时前
Java中断
java·开发语言
施棠海6 小时前
监听与回调的三个demo
java·开发语言
時肆4856 小时前
C语言造轮子大赛:从零构建核心组件
c语言·开发语言
EniacCheng6 小时前
Windows11 Qt MSVC配置
qt·msvc·调试·winmain
赴前尘6 小时前
golang 查看指定版本库所依赖库的版本
开发语言·后端·golang
de之梦-御风6 小时前
【C#.Net】C#开发的未来前景
开发语言·c#·.net
知乎的哥廷根数学学派7 小时前
基于数据驱动的自适应正交小波基优化算法(Python)
开发语言·网络·人工智能·pytorch·python·深度学习·算法
de之梦-御风7 小时前
【C#.Net】C#在工业领域的具体应用场景
开发语言·c#·.net
sunfove7 小时前
将 Python 仿真工具部署并嵌入个人博客
开发语言·数据库·python
Learner7 小时前
Python类
开发语言·python