Qt:关于16进制数转化那些事
前言
由于当时做UDP
通信的时候使用16进制数与QString
的相互转换,但是当时我所要求的转换不仅仅是转化过去就行了,我还有字节数要求,就是这个16进制数占据多少位那么转化后的数据就该占据多大的空间。
正文
1 将 QString
转换为16进制字符串
1.1 当 QString
中的内容不是数字时
对于这种你将QString
转换成16进制字符串并没有办法节省空间。
要将 QString
转换为其对应的16进制表示,可以使用 QByteArray
的 toHex()
方法。首先,将 QString
转换为 QByteArray
,然后调用 toHex()
方法获取16进制表示。
#include <QString>
#include <QByteArray>
#include <QDebug>int main() {QString originalString = "Hello, Qt!";// 将 QString 转换为 QByteArray(使用 UTF-8 编码)QByteArray byteArray = originalString.toUtf8();// 将 QByteArray 转换为16进制字符串QByteArray hexData = byteArray.toHex();// 将 QByteArray 转换为 QStringQString hexString = QString::fromUtf8(hexData);qDebug() << "原始字符串:" << originalString;qDebug() << "16进制字符串:" << hexString;return 0;
}
输出:
原始字符串: "Hello, Qt!"
16进制字符串: "48656c6c6f2c20517421"
1.2 当 QString
中的内容是数字时
1.2.1当 QString
中的内容是十进制数字时
#include <QString>
#include <QByteArray>
#include <QDebug>int main() {QString decimalString = "4953";bool ok;// 将 QString 转换为整数,占据四个字节,基数为16int number = decimalString.toInt(&ok);if (ok) {qDebug() << "10进制字符串" << decimalString << "转换为整数:" << number;} else {qDebug() << "转换失败";}// 初始化QByteArrayQByteArray bArray;bArray.resize(4);for (int i = 0; i < bArray.size(); i++) {bArray[i] = 0;}// 占据两个字节bArray[0] = number / 0x100;bArray[1] = number % 0x100;qDebug()<<"bArray: "<<bArray<<bArray.size();QByteArray bs = bArray.toHex();qDebug()<<"转化后的16进制数为:"<<bs<<bs.size();return 0;
}
这里可以节省一倍的空间,4953
的字符串类型占据四个字节,转换成int
类型占据四个字节,但是我巧妙将它放到QByteArray
中就只用了两个字节。下面结果打印为4是因为我初始将bArray
的大小初始化为4,但是我后面两个字节没有用。
运行结果
1.2.1当 QString
中的内容是十六进制数字时
#include <QString>
#include <QByteArray>
#include <QDebug>int main() {QString hexString = "1A3F";bool ok;// 将 QString 转换为整数,占据四个字节,基数为16int number = hexString.toInt(&ok, 16);if (ok) {qDebug() << "16进制字符串" << hexString << "转换为整数:" << number;} else {qDebug() << "转换失败";}// 初始化QByteArrayQByteArray bArray;bArray.resize(4);for (int i = 0; i < bArray.size(); i++) {bArray[i] = 0;}// 占据两个字节bArray[0] = number / 0x100;bArray[1] = number % 0x100;qDebug()<<"bArray: "<<bArray<<bArray.size();return 0;
}
这里可以节省一倍的空间,1A3F
的字符串类型占据四个字节,转换成int
类型占据四个字节,但是我巧妙将它放到QByteArray
中就只用了两个字节。
运行结果
1.2.2当 QString
中的内容是有前缀的十六进制数字时
有时16进制字符串可能包含前缀,如 0x
或 #
,在进行转换时需要去除这些前缀。
1.2.2.1 处理带有 0x
前缀的16进制字符串
#include <QString>
#include <QDebug>
#include <QByteArray>
int main() {QString hexString = "0x1A3F";// 检查并移除前缀if (hexString.startsWith("0x") || hexString.startsWith("0X")) {hexString = hexString.mid(2);}bool ok = false;int number = hexString.toInt(&ok, 16);if (ok) {qDebug() << "16进制字符串(去除前缀)" << hexString << "转换为整数:" << number;} else {qDebug() << "转换失败";}// 初始化QByteArrayQByteArray bArray;bArray.resize(4);for (int i = 0; i < bArray.size(); i++) {bArray[i] = 0;}// 占据两个字节bArray[0] = number / 0x100;bArray[1] = number % 0x100;qDebug()<<"bArray: "<<bArray<<bArray.size();return 0;
}
其实处理步骤和没有前缀的差不多,就多了一个去除前缀的操作。
运行结果
1.2.2.2 处理带有 #
前缀的16进制颜色代码
#include <QString>
#include <QDebug>
#include <QByteArray>
int main() {QString colorCode = "#FF5733";// 移除 '#' 前缀if (colorCode.startsWith("#")) {colorCode = colorCode.mid(1);}bool ok = false;unsigned int colorValue = colorCode.toUInt(&ok, 16);if (ok) {qDebug() << "颜色代码" << colorCode << "转换为数值:" << colorValue;} else {qDebug() << "转换失败";}// 初始化QByteArrayQByteArray bArray;bArray.resize(4);for (int i = 0; i < bArray.size(); i++) {bArray[i] = 0;}// 占据三个字节bArray[0] = colorValue / 0x10000;bArray[1] = (colorValue % 0x10000) / 0x100;bArray[2] = colorValue % 0x100;qDebug()<<"bArray: "<<bArray<<bArray.size();QString str = bArray.toHex().toUpper();qDebug()<<"hex:"<<str;
}
其实处理步骤和没有前缀的差不多,就多了一个去除前缀的操作。
运行结果
2 将16进制字符串转换回 QString
2.1当转换后的QString
字符串内容不是数字时
将16进制字符串转换回原始的 QString
需要进行逆向操作,即将16进制字符串转换为 QByteArray
,然后再转换为 QString
。
#include <QString>
#include <QByteArray>
#include <QDebug>int main() {// 当16进制字符串内容不是数字时,就只能用字符串,或者QByteArray来表示了,这里使用字符串来表示QString hexString = "48656c6c6f2c20517421";// 将 QString 转换为 QByteArrayQByteArray hexData = hexString.toUtf8();// 将16进制字符串转换为 QByteArrayQByteArray byteArray = QByteArray::fromHex(hexData);// 将 QByteArray 转换为 QString(使用 UTF-8 编码)QString originalString = QString::fromUtf8(byteArray);qDebug() << "16进制字符串:" << hexString;qDebug() << "原始字符串:" << originalString;return 0;
}
输出:
16进制字符串: "48656c6c6f2c20517421"
原始字符串: "Hello, Qt!"
2.1当转换后的QString
字符串内容是数字时
#include <QString>
#include <QByteArray>
#include <QDebug>int main(int argc, char *argv[])
{QCoreApplication a(argc, argv);int decimalData = 23;QString hex = QString::number(decimalData,16).toUpper();qDebug()<<"转换的16进制数为:"<<hex<<" 所占的大小为:"<<hex.size();
}
运行结果
小结
其实QString
和 QByteArray
类型的数据很像,QByteArray
一个数组空间就是一个字节,而QString
中一个字符就是一个字节,但是QByteArray
特殊在它能用来存储16进制数,1个字节是8bit,最大能存放一个FF
,也就是说对于QByteArray
一个字节能存放FF
而对于QString
来说需要两个字节,毕竟FF
是两个字母嘛。