当前位置: 首页 > news >正文

Qt 数据QByteArray与QString处理与转换全指南

1. 核心概念解析

1.1 原始字节数据、ASCII字符串、十六进制字符串

类型定义示例用途
原始字节数据计算机底层数据形式,由8位二进制组成(范围0x00~0xFF),无直接可读性。0x48, 0x65, 0x6C(3个字节)串口传输、文件存储、加密计算
ASCII字符串由可打印ASCII字符(0x20~0x7E)组成的文本,每个字符对应1个字节。"Hello"(字节:0x48, 0x65, 0x6C人类可读的文本交互
十六进制字符串用2个十六进制字符表示1个字节的文本形式(0-9A-F),可读但冗长。"48656C"(表示3个字节:0x48, 0x65, 0x6C调试日志、二进制数据存储

关键关系

  • 原始字节是底层数据,ASCII和十六进制字符串是其可读表示。
  • 转换需通过特定函数(如toHex()fromHex()toUtf8())。

2. QByteArray 与 QString 的转换

2.1 QByteArray

概念

QByteArray 是 Qt 中用于存储原始二进制数据(如字节数组)的类。它类似于 C++ 的 std::vector<char>,但提供了更多便捷的方法和 Qt 的内存管理优化。

关键特性
  • 存储二进制数据:可以存储任意字节序列(如图片、音频、加密数据等)。
  • 自动内存管理:支持深拷贝和浅拷贝(通过 fromRawData 共享外部数据)。
  • 编码无关:不涉及字符编码,仅处理原始字节。
  • 常用操作
    • 追加数据:append()
    • 转换为十六进制:toHex()
    • 转换为 Base64:toBase64()
    • 子数组:mid()
    • 与 QString 转换:fromUtf8()toUtf8() 等。

2.2 QString

概念

QString 是 Qt 中用于存储Unicode 字符串的类,支持多语言文本处理(如中文、日文等)。它内部使用 UTF-16 编码,提供了丰富的字符串操作方法。

关键特性
  • Unicode 支持:内部使用 UTF-16,可正确处理非 ASCII 字符。
  • 隐式共享(写时复制):多个 QString 共享同一数据,修改时才复制,节省内存。
  • 丰富的操作
    • 拼接:+append()
    • 查找替换:indexOf()replace()
    • 子字符串:left()mid()right()
    • 转换为数字:toInt()toDouble()
    • 与 QByteArray 转换:toUtf8()fromUtf8() 等。

2.3 核心函数与方法

(1) QString → QByteArray
方法作用推荐场景
toUtf8()将Unicode文本编码为UTF-8格式的二进制数据(跨平台兼容)。网络传输、文件存储、国际文本处理。
toLatin1()编码为Latin-1(ISO-8859-1),非ASCII字符会丢失。仅限纯ASCII或Latin-1文本。
toLocal8Bit()根据系统本地编码(如GBK)转换,行为不一致。依赖操作系统的本地化场景(慎用)。

示例

QString text = "Hello, 世界!";
QByteArray utf8Data = text.toUtf8(); // 正确:UTF-8编码
QByteArray latin1Data = text.toLatin1(); // 错误:中文会丢失
(2) QByteArray → QString
方法作用推荐场景
fromUtf8()将UTF-8二进制数据解码为Unicode文本(支持所有语言字符)。处理网络数据、文件内容、国际文本。
fromLatin1()解码Latin-1二进制数据,仅适用于ASCII/Latin-1范围。纯ASCII或Latin-1文本。
fromLocal8Bit()根据系统本地编码解码,行为不可靠。依赖操作系统的本地化场景(慎用)。

示例

QByteArray utf8Data = "\xE4\xB8\x96"; // "世"的UTF-8编码
QString text = QString::fromUtf8(utf8Data); // 正确:解码为Unicode
QString latin1Text = QString::fromLatin1(utf8Data); // 错误:乱码
(3) 避免直接构造
  • 错误示例
QByteArray data = "世界";
QString text(data); // 隐式调用fromLatin1(),乱码!
  • 正确做法
QString text = QString::fromUtf8(data); // 显式指定UTF-8

2.4 常见问题与解决

(1) 中文乱码
  • 原因:编码/解码方式不匹配(如用toLatin1()处理中文)。
  • 解决:始终显式使用toUtf8()fromUtf8()
(2) 无效编码处理
  • 场景:输入数据包含无效UTF-8序列(如截断的字节)。
  • 解决
QByteArray data = "\xFF\xFF"; // 无效UTF-8
QString text = QString::fromUtf8(data).normalized(QString::NormalizationForm_C);

3. 十六进制数据处理(Hex转换)

3.1 核心函数

3.1 核心函数

函数作用输入/输出
QByteArray::toHex()将二进制数据转换为十六进制字符串(每个字节→2个十六进制字符)。输入:QByteArray → 输出:QString(小写)
QByteArray::fromHex()将十六进制字符串转换为二进制数据(每2个字符→1个字节)。输入:QString/QByteArray → 输出:QByteArray

示例

// 二进制 → 十六进制字符串
QByteArray data = "\x48\x65\x6C";
QString hexStr = data.toHex().toUpper(); // "48656C"(大写)// 十六进制字符串 → 二进制
QString hexInput = "48656C";
QByteArray byteData = QByteArray::fromHex(hexInput.toUtf8()); // 0x48, 0x65, 0x6C

3.2 实战场景:串口通信

(1) 发送Hex数据
if (ui->checkBHexSend->isChecked()) {QString hexStr = ui->lineEdit->text().trimmed();QByteArray byteData = QByteArray::fromHex(hexStr.toUtf8()); // 转换Hex字符串为二进制serialPort->write(byteData); // 发送原始字节
} else {QString text = ui->lineEdit->text();serialPort->write(text.toUtf8()); // 直接发送文本(UTF-8编码)
}
(2) 接收Hex数据显示
QByteArray receivedData = serialPort->readAll();
QString hexDisplay = receivedData.toHex().toUpper(); // 转换为大写Hex字符串
ui->textEdit->append(hexDisplay); // 显示Hex格式

4. 完整示例:文本 ↔ 二进制 ↔ Hex

示例1:文本 → UTF-8 → Hex

QString text = "Qt";
QByteArray utf8Data = text.toUtf8(); // Unicode → UTF-8二进制
QString hexStr = utf8Data.toHex().toUpper(); // 二进制 → Hex字符串("5174")
qDebug() << "Hex:" << hexStr;

示例2:Hex → 二进制 → 文本

QString hexInput = "E4B896"; // "世"的UTF-8 Hex
QByteArray utf8Data = QByteArray::fromHex(hexInput.toUtf8()); // Hex → UTF-8二进制
QString decodedText = QString::fromUtf8(utf8Data); // UTF-8 → Unicode
qDebug() << "Text:" << decodedText; // 输出:"世"

示例3:文件读写(文本 ↔ 二进制)

// 写入文件(QString → QByteArray → 文件)
QString text = "Hello, Qt!";
QFile file("output.txt");
if (file.open(QIODevice::WriteOnly)) {file.write(text.toUtf8()); // 显式UTF-8编码file.close();
}// 读取文件(QByteArray → QString)
if (file.open(QIODevice::ReadOnly)) {QByteArray data = file.readAll();QString text = QString::fromUtf8(data); // 显式UTF-8解码qDebug() << "Read:" << text;file.close();
}

5. 总结与最佳实践

  1. 编码一致性
    • 始终显式使用toUtf8()fromUtf8(),避免隐式转换导致的乱码。
    • 跨平台场景优先选择UTF-8。
  2. Hex转换场景
    • 用户输入Hex字符串时,用fromHex()转换为二进制发送。
    • 接收二进制数据后,用toHex()显示为Hex字符串。
  3. 性能优化
    • 批量处理大数据,预分配内存。
    • 避免在循环中频繁调用转换函数。
  4. 错误处理
    • 检查输入有效性(如Hex字符串是否合法、UTF-8是否有效)。
    • 使用QTextCodec检测编码问题。

文章转载自:
http://shamanism .zekgq.cn
http://miscast .zekgq.cn
http://futurologist .zekgq.cn
http://raschel .zekgq.cn
http://finnip .zekgq.cn
http://intimidator .zekgq.cn
http://furnaceman .zekgq.cn
http://telukbetung .zekgq.cn
http://shutoff .zekgq.cn
http://granddam .zekgq.cn
http://unheroic .zekgq.cn
http://ethambutol .zekgq.cn
http://iskenderun .zekgq.cn
http://saturnalia .zekgq.cn
http://theodidact .zekgq.cn
http://orthowater .zekgq.cn
http://hindoo .zekgq.cn
http://uranous .zekgq.cn
http://huskiness .zekgq.cn
http://stigmatization .zekgq.cn
http://aspect .zekgq.cn
http://crystalligerous .zekgq.cn
http://infusionist .zekgq.cn
http://transcurrence .zekgq.cn
http://minnesotan .zekgq.cn
http://taroc .zekgq.cn
http://calyciform .zekgq.cn
http://plashy .zekgq.cn
http://precursive .zekgq.cn
http://hewn .zekgq.cn
http://www.dtcms.com/a/293963.html

相关文章:

  • QT的moveToThread 用法
  • Java按模板导出Excel
  • LoRA 低秩矩阵实现参数高效的权重更新
  • 2025 ACT 汽车功能安全相关PPT分享
  • 《计算机网络》实验报告七 HTTP协议分析与测量
  • 【硬件-笔试面试题】硬件/电子工程师,笔试面试题汇总版,持续更新学习,加油!!!
  • 场效应管和模电的关于、学习
  • 【盘古100Pro+开发板实验例程】FPGA | Modelsim 的使用和 do 文件编写
  • SpringBoot 使用Rabbitmq
  • rust嵌入式开发零基础入门教程(一)
  • FSHNet:高效目标检测新突破
  • rust嵌入式开发零基础入门教程(五)
  • Python应用指南:构建和获取全球地铁线路数据及可视化
  • HarmonyOS学习记录5
  • 【形态学变换】——图像预处理(OpenCV)
  • (nice!!!)(LeetCode 每日一题) 1717. 删除子字符串的最大得分 (贪心)
  • 昨天去看了电科金仓的发布会,有点东西!
  • AI营销核心技术解析:运作机制与行业应用实例
  • 【软件系统架构】系列七:嵌入式系统性能深入解析
  • 华为云中,列表中的镜像无法删除可能由多种原因导致
  • 华为云开发者空间 × DeepSeek-R1 智能融合测评:云端开发与AI客服的协同进化
  • WPF的一些基础知识学习记录
  • 设计模式 八:原型模式 (Prototype Pattern)
  • Spring Boot全局异常处理:一网打尽Controller层异常,@RestControllerAdvice解析
  • 设计模式(单例)
  • 界面组件DevExpress WPF中文教程:Grid - 如何过滤节点?
  • Linux下SVN常用指令
  • 设计模式代码总结
  • Android MediaCodec 的使用和源码实现分析
  • 路由器与交换机的区别