Linux下Qt C++中以\x开头的UTF-8 十六进制编码转化为中文的思考

Linux下Qt C++中以\x开头的UTF-8 十六进制编码转化为中文

前言

最近使用wpa_cli扫描wifi列表时发现,扫出来的中文名字会表现为一堆十六进制码,比如“中文”这两个字对应的就是"\xe4\xb8\xad\xe6\x96\x87"。找个在线转码网站就能知道它们的中文意思,但这不是我需要的,必须找到一种方式将这些编码转化为中文。

尝试方案

No.1 echo

我发现了 echo -n '我是字符串'这个指令能够将那堆编码转化成字符串,于是就写了个程序来处理一下:

//Widget.cpp
//主函数内
	QStringList list;
    list.append("fjhwifjiw");
    list.append("hwfuwfuiw");
    list.append("\xe9\x9f\xa6\xe5\xbe\xb7\xe6\x96\xaf");
    
    // 遍历QStringList
    for (int i = 0; i < list.size(); i++) {
    
    
        // 使用sprintf将元素插入到命令字符串中
        char cmd[50];
        sprintf(cmd, "echo -n '%s\n'>>./wifi.txt", list[i].toLocal8Bit().constData()); // 在命令字符串末尾添加换行符
        // 执行命令
        system(cmd);
    }

这样子是可以的,不过现在是手动添加list的项,我需要动态添加list的项,因此改成:

//Widget.cpp
//主函数内
	QString filePath = "./input.txt"; // 替换为你的文本文件路径
    QList<QString> list = readLinesFromFile(filePath);

    // 输出文件中的每一行
    for (const QString& line : list) {
    
    
        qDebug() << line;
    }

    // 遍历QStringList
    for (int i = 0; i < list.size(); i++) {
    
    
        // 使用sprintf将元素插入到命令字符串中
        char cmd[60];
        sprintf(cmd, "echo -n '%s\n'>>./wifi.txt", list[i].toLocal8Bit().constData()); // 在命令字符串末尾添加换行符
        // 执行命令
        system(cmd);
    }
//成员方法
QList<QString> Widget::readLinesFromFile(const QString& filePath) {
    
    
    QFile file(filePath);
    if (!file.open(QIODevice::ReadOnly)) {
    
    
        // 处理文件打开失败的情况
        return QList<QString>();
    }

    QList<QString> lines;
    QTextStream in(&file);
    while (!in.atEnd()) {
    
    
        QString line = in.readLine();
        lines.append(line);
    }

    file.close();
    return lines;
}

后面它报出错误*** stack smashing detected ***: terminated;查了半天没什么结果就不了了之(如果有感兴趣可以试一下告诉我原因)
想了又想,又使用另外一种方法读出文件内容存放到QStringList里:

QFile file("./input.txt");
    if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
    
    
        // 处理文件打开失败的情况
        //return -1;
        return;
    }
    // 创建一个 QTextStream 对象来读取文件内容
    QTextStream in(&file);
    // 创建一个 QList<QString> 对象来存储文件内容
    QStringList lines;
    // 逐行读取文件内容,并将其添加到 QList<QString> 中
    while (!in.atEnd()) {
    
    
        QString line = in.readLine();
        lines.append(line);
    }
    //关闭文件
    file.close();
    lines<<"\xe9\x9f\xa6\xe5\xbe\xb7\xe6\x96\xaf";
    qDebug()<<lines<<endl;
    //遍历QStringList
    for (int i = 0; i < lines.size(); i++) {
    
    
        // 使用sprintf将元素插入到命令字符串中
        char cmd[60];
        sprintf(cmd, "echo -n '%s\n'>>./wifi.txt", lines[i].toLocal8Bit().constData()); // 在命令字符串末尾添加换行符
        // 执行命令
        system(cmd);
    }

然后又发现文件里面的数据是"\xe9\x9f\xa6\xe5\xbe\xb7\xe6\x96\xaf",到QStringList里面变成了“\xe9\x9f\xa6\xe5\xbe\xb7\xe6\x96\xaf”,据说是它会发生编码转化,变成UTF-16了,弄了半天两根反斜杠没删去半根又被我多整出了两根,又不了了之了(如果有感兴趣可以试一下再告诉我原因)

No.2 UTF-8->GBK->UTF-8

和前辈聊天时想到这个方法,看看会不会有什么神奇现象发生。这种方案就是将这UTF-8 16进制编码转化成GBK,然后再转回UTF-8,因此又编了个程序:

//Widget.cpp
//主函数内
QString utf8String = "\xe9\x9f\xa6\xe5\xbe\xb7\xe6\x96\xaf";
    QString gbkString = convertToGbk(utf8String);

    //QString gbkString = "这是一段GBK编码的文本。"; // 假设这是你的GBK编码字符串
    QString utf81String = convertToUtf8(gbkString); // 将GBK编码转换为UTF-8编码


    QLabel* label = new QLabel(utf81String,this);
    label->show();
//成员方法    
    QString Widget::convertToGbk(const QString& utf8String) {
    
    
    QTextCodec* codec = QTextCodec::codecForName("GBK");
    if (codec) {
    
    
        QString gbkString = codec->toUnicode(utf8String.toLocal8Bit());
        return gbkString;
    } else {
    
    
        return QString(); // 返回空字符串表示转换失败
    }
}
//成员方法 
QString Widget::convertToUtf8(const QString& gbkString) {
    
    
    QTextCodec* codec = QTextCodec::codecForName("GBK");
    if (codec) {
    
    
        QString utf8String = codec->fromUnicode(gbkString);
        return utf8String;
    } else {
    
    
        return QString(); // 返回空字符串表示转换失败
    }
}

果然“神奇”的事情TA真的发生了,两个中文一般可以转化出来,三个的就只会转化成前两个字后面就是��,多个中文字有时候能完全转出来,有时候也会有��,所以又不了了之了(如果有感兴趣可以试试还是再一次告诉我原因)

No.3 GPT

GPT给了一个类似我曾经使用过方案,这里没有深入测试:

//我们可以使用QString类中的fromUtf8函数将UTF-8编码的字符串转换为QString对象
    QString str = QString::fromUtf8("\xe7\x82\xac\xe8\x8f\xb1");
//使用QTextCodec类的codecForLocale函数获取当前系统的编码方式,进而使用QTextCodec类的toUnicode函数将QString对象转换为可读的中文字符串
    QTextCodec *codec = QTextCodec::codecForLocale();
    QString decodedStr = codec->toUnicode(str.toUtf8());
//使用qPrintable宏将QString对象转换为C风格的字符串,以便打印输出
    qDebug() << qPrintable(decodedStr);

实现方案

有一位大神给出了最终的建议,还是自己知识太浅薄了,不知道还有这个方法:

//只是如果是\x和非\x字符兼有的话要自己读取判断一下,如果不是\x开头就直接读取一个字符,如果是\x开头就读取\x后面2个字符,然后用QByteArray::fromHex()转成一个字符,最后把拼成的QByteArray转成QString
QByteArray raw = "\\xe9\\x9f\\xa6\\xe5\\xbe\\xb7\\xe6\\x96\\xaf";
QByteArray converted = QByteArray::fromHex(raw);
QString name = QString::fromUtf8(converted);
qDebug() << name;

在此基础就可以改造自己的程序,读取文本里面的数据,有编码就进行中文转化,再存到QStringList里:

 // 打开文件并创建QTextStream对象
        QFile file("./input.txt");
        QStringList list;
        if (file.open(QIODevice::ReadOnly)) {
    
    
            QTextStream in(&file);
            while (!in.atEnd()) {
    
    
                // 读取一行文本
                QString line = in.readLine();
                // 检查行开头是否为"\\"
                if (line.startsWith("\\")) {
    
    
                    // 进行处理
                    QByteArray raw = line.toUtf8();
                    QByteArray converted = QByteArray::fromHex(raw);
                    QString name = QString::fromUtf8(converted);
                    list.append(name);
                    qDebug() << name;
                } else {
    
    
                    // 直接将行赋值给QString
                    QString name = line;
                    list.append(name);
                    qDebug() << name;
                }
            }
            file.close();
        } else {
    
    
            qDebug() << "Failed to open file";
        }
        qDebug()<<list<<endl;

这样就完成了我的需求

猜你喜欢

转载自blog.csdn.net/qq_45875853/article/details/134345356