Qt 源代码文件格式批量改为UTF-8

#include "widget.h"

#include <QHBoxLayout>
#include <QVBoxLayout>
#include <QDir>
#include <QTextStream>
#include <QDebug>
#include <QFileDialog>
#include <QTextCodec>
#include <QString>

#include <windows.h>
#include <stdio.h>

#pragma execution_character_set("utf-8")

Widget::Widget(QWidget *parent)
    : QWidget(parent)
{
    le_fileDir = new QLineEdit(this);
    pb_selectFileDir = new QPushButton(tr("选择文件目录"), this);
    pb_ok = new QPushButton("ok", this);

    QHBoxLayout *topLayout = new QHBoxLayout;
    topLayout->addWidget(new QLabel("文件目录:", this));
    topLayout->addWidget(le_fileDir);
    topLayout->addWidget(pb_selectFileDir);
    topLayout->setSpacing(10);

    QVBoxLayout *mainLayout = new QVBoxLayout;
    mainLayout->addLayout(topLayout);
    mainLayout->addWidget(pb_ok, 0, Qt::AlignRight);

    this->setLayout(mainLayout);

    connect(pb_ok, &QPushButton::clicked, this, &Widget::slt_ok);
    connect(pb_selectFileDir, &QPushButton::clicked, this, &Widget::slt_selectFileDir);
}

Widget::~Widget()
{

}

void Widget::initData()
{

}

QStringList Widget::getAllFilePath(QString &strDir)
{
    QStringList filePathLst;
    QDir dir(strDir);
    if (!dir.exists())
    {
        return filePathLst;
    }
    dir.setFilter(QDir::Dirs | QDir::Files);
    dir.setSorting(QDir::DirsFirst);
    //dir.setNameFilters(QStringList() << "*.h" << "*.cpp" << "*.pro");
    QFileInfoList fileLst = dir.entryInfoList();
    for (QFileInfo fileInfo : fileLst)
    {
        if (fileInfo.fileName() == "." | fileInfo.fileName() == "..")
        {
            continue;
        }

        if (fileInfo.isDir())
        {
            filePathLst += getAllFilePath(fileInfo.absoluteFilePath());
        }
        else
        {
            QString filePath = fileInfo.absoluteFilePath();
            if (filePath.endsWith(".h") || filePath.endsWith(".cpp") || filePath.endsWith(".pro"))
            {
                filePathLst.append(filePath);
            }
        }
      }

    return filePathLst;
}

void Widget::slt_ok()
{
    QString fileDirPath = le_fileDir->text();
    QStringList filePathLst = getAllFilePath(fileDirPath);
    for (QString filePath : filePathLst)
    {
        //QString unicodeString = "Some Unicode string";
        QFile fileIn(filePath);
        if (!fileIn.open(QIODevice::ReadOnly | QIODevice::Text))
        {
            qDebug() << "Warning:" << filePath;
            continue;
        }
        QByteArray str = fileIn.readAll();
        QString resText;
        bool bok = GetCorrectUnicode(str, resText);
        if (!bok) continue;
        //fileIn.remove();
        fileIn.close();

        this->writerFile(filePath, resText);
    }

    qDebug() << "Ok Finished!";
}

void Widget::slt_selectFileDir()
{
    QString srcDirPath = QFileDialog::getExistingDirectory(this, "choose src Directory", "./");

     if (srcDirPath.isEmpty())
     {
         return;
     }
     else
     {
         le_fileDir->setText(srcDirPath);
     }
}

//编码转换
bool Widget::GetCorrectUnicode(const QByteArray &ba, QString &text)
{
    QTextCodec::ConverterState state;
    QTextCodec *codec = QTextCodec::codecForName("UTF-8");
    text = codec->toUnicode( ba.constData(), ba.size(), &state);
    //qDebug() <<state.invalidChars;
    if(state.invalidChars == 3)
    {//3是unicode
        //text = QTextCodec::codecForName("Unicode")->toUnicode(ba);
        return false;
    }
    //等于是是GBK
    else if (state.invalidChars > 0)
    {
        text = QTextCodec::codecForName("GBK")->toUnicode(ba);
        //text = AnsiToUtf8(ba);
    }
    else
    {
        //text = ba;
        return false;
    }

    return true;
}


void Widget::writerFile(QString filePath, const QString &strContent)
{
    QFile fileOut(filePath);
    fileOut.open(QIODevice::WriteOnly | QIODevice::Truncate);

    QTextStream streamFileOut(&fileOut);
    streamFileOut.setCodec("utf-8");
    streamFileOut.setGenerateByteOrderMark(true);
    streamFileOut << strContent;
    streamFileOut.flush();
}

 

#ifndef WIDGET_H
#define WIDGET_H
 
#include <QWidget>
#include <QPushButton>
#include <QLineEdit>
#include <QLabel>
 
class Widget : public QWidget
{
    Q_OBJECT
 
public:
    Widget(QWidget *parent = 0);
    ~Widget();
    void initData();
    QStringList getAllFilePath(QString &strDir);
 
    QByteArray AnsiToUtf8(const QByteArray &ansi);
 
    void writerFile(QString filePath, const QString &strContent);
 
protected slots:
    void slt_ok();
    void slt_selectFileDir();
 
protected:
    bool GetCorrectUnicode(const QByteArray &ba, QString &text);
 
protected:
    QLineEdit *le_fileDir;
    QPushButton *pb_selectFileDir;
    QPushButton *pb_ok;
};
 
#endif // WIDGET_H

 

 

最重要的是 setGenerateByteOrderMark 函数的使用时机,官网上是这么解释的:

If generate is true and a UTF codec is used, QTextStream will insert the BOM (Byte Order Mark) before any data has been written to the device. If generate is false, no BOM will be inserted. This function must be called before any data is written. Otherwise, it does nothing.

See also generateByteOrderMark() and bom().

百度翻译一下:

如果generate为true并且使用了UTF编解码器,那么QTextStream将在将任何数据写入设备之前插入BOM(字节顺序标记)。如果generate为false,则不插入BOM表。必须在写入任何数据之前调用此函数。否则,它什么也不做。

另请参见generateByteOrderMark()和bom()。

windows下:如果代码中有中文的话就得设置成true,不然编译不通过。而且得设置在写数据之前才会有效。

上一篇:vbs调用批处理、PowerShell传参,加域等


下一篇:Codeforces Round #715 (Div. 2) D. Binary Literature (构造)