Qt:关于16进制数转化那些事

前言

由于当时做UDP通信的时候使用16进制数与QString的相互转换,但是当时我所要求的转换不仅仅是转化过去就行了,我还有字节数要求,就是这个16进制数占据多少位那么转化后的数据就该占据多大的空间。

正文

1 将 QString 转换为16进制字符串

1.1 当 QString中的内容不是数字时

对于这种你将QString转换成16进制字符串并没有办法节省空间。
要将 QString 转换为其对应的16进制表示,可以使用 QByteArraytoHex() 方法。首先,将 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 转换为 QString
    QString 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 转换为整数,占据四个字节,基数为16
    int number = decimalString.toInt(&ok);
    if (ok) {
    
    
        qDebug() << "10进制字符串" << decimalString << "转换为整数:" << number;
    } else {
    
    
        qDebug() << "转换失败";
    }
    // 初始化QByteArray
    QByteArray 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 转换为整数,占据四个字节,基数为16
    int number = hexString.toInt(&ok, 16);
    if (ok) {
    
    
        qDebug() << "16进制字符串" << hexString << "转换为整数:" << number;
    } else {
    
    
        qDebug() << "转换失败";
    }
    // 初始化QByteArray
    QByteArray 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() << "转换失败";
    }

    // 初始化QByteArray
    QByteArray 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() << "转换失败";
    }

    // 初始化QByteArray
    QByteArray 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 转换为 QByteArray
    QByteArray hexData = hexString.toUtf8();
    
    // 将16进制字符串转换为 QByteArray
    QByteArray 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();
}
运行结果

在这里插入图片描述

小结

其实QStringQByteArray类型的数据很像,QByteArray一个数组空间就是一个字节,而QString中一个字符就是一个字节,但是QByteArray特殊在它能用来存储16进制数,1个字节是8bit,最大能存放一个FF,也就是说对于QByteArray一个字节能存放FF而对于QString来说需要两个字节,毕竟FF是两个字母嘛。

猜你喜欢

转载自blog.csdn.net/m0_71489826/article/details/142406342