Qt6实现统计代码信息

本文介绍了一个使用Qt开发的小软件,用于统计.cpp/.c源文件、.h头文件数量、总代码行数和有效代码行数。软件包括选择文件路径、保存读取代码、获取代码行数以及保留有效代码的功能。
摘要由CSDN通过智能技术生成

最近需要统计几份代码里的相关信息,如.cpp/.c源文件个数、.h头文件个数、总代码行数、有效代码行数等,文件个数和总代码行数手动计算倒是不难,而有效代码行数是要计算除去空行和注释外的代码行数,对于代码量多的话就费时费力了,所以本人就写个小软件来实现相关功能,具体代码如下:

简单的ui文件如下:

1、选择保存路径和选择代码文件

//获取保存路径
void ValidCode::getSavePath()
{
    //默认打开桌面路径
    QString desktopPath = QStandardPaths::writableLocation(QStandardPaths::DesktopLocation);
    QString filePath = QFileDialog::getOpenFileName(nullptr, "选择代码文件", desktopPath, "Text files (*.txt)");
    ui->editSaveFile->setText(filePath);
}
//获取代码路径
void ValidCode::getCodePath()
{
    //默认打开桌面路径
    QString desktopPath = QStandardPaths::writableLocation(QStandardPaths::DesktopLocation);
    QString folderPath = QFileDialog::getExistingDirectory(nullptr, "选择文件夹", desktopPath);
    ui->editCodeFile->setText(folderPath);
}

这里选择一个保存路径是方便查看和复制代码。

2、保存和读取代码文件

//保存和读取代码文件
void ValidCode::saveReadFile()
{
    QString savePath = ui->editSaveFile->text();
    QString codePath = ui->editCodeFile->text();

    if(savePath.isEmpty() || codePath.isEmpty()){
        QMessageBox emptyWarnBox;
        emptyWarnBox.warning(nullptr, "Warn", "保存/代码文件路径为空");
        return;
    }

    QStringList selectedFilters;

    //文件类型选择
    QMessageBox msgBox;
    msgBox.setWindowTitle("Tips");
    msgBox.setText("请选择保存、读取的文件类型");
    QPushButton* cppcButton = msgBox.addButton(".cpp/.c", QMessageBox::YesRole);
    QPushButton* hButton = msgBox.addButton(".h", QMessageBox::YesRole);
    QPushButton* cppchButton = msgBox.addButton(".cpp/.c和.h", QMessageBox::YesRole);
    QPushButton* closeButton = msgBox.addButton(QMessageBox::Close);
    closeButton->hide();    // 隐藏消息框关闭按钮,以能使用右上角的关闭按钮
    msgBox.exec();

    if (msgBox.clickedButton() == cppcButton) {
        selectedFilters = QStringList() << "*.cpp" << "*.c";
    }
    else if (msgBox.clickedButton() == hButton) {
        selectedFilters = QStringList() << "*.h";
    }
    else if (msgBox.clickedButton() == cppchButton) {
        selectedFilters = QStringList() << "*.cpp" << "*.c" << "*.h";
    }
    else {
        return;
    }

    QFile outputFile(savePath);
    if (!outputFile.open(QIODevice::WriteOnly | QIODevice::Text | QIODevice::Truncate)) {
        QMessageBox editFileErrorBox;
        editFileErrorBox.critical(nullptr, "Error", "无法打开保存文件");
        return;
    }

    QTextStream out(&outputFile);
    int cppcFileNum = 0;
    int hFileNum = 0;
    QString fileNum;

    processFolder(codePath, out, cppcFileNum, hFileNum, selectedFilters);

    if (msgBox.clickedButton() == cppcButton) {
        fileNum = ".cpp/.c 源文件个数:" + QString::number(cppcFileNum);
    }
    else if (msgBox.clickedButton() == hButton) {
        fileNum = ".h 头文件个数:" + QString::number(hFileNum);
    }
    else if (msgBox.clickedButton() == cppchButton) {
        fileNum = ".cpp/.c 源文件个数:" + QString::number(cppcFileNum) + "\n.h 头文件个数:" + QString::number(hFileNum);
    }
    ui->browseReadFile->setText(fileNum);
}


//读取代码文件内容,保存到指定路径下,同时记录不同的文件类型个数
void ValidCode::processFolder(const QString &folderPath, QTextStream &out, int &cppcCount, int &hCount, const QStringList &filters)
{
    QDir folder(folderPath);
    if (!folder.exists()) {
        QMessageBox folderErrorBox;
        folderErrorBox.critical(nullptr, "Error", "代码文件不存在");
        return;
    }

    QStringList files = folder.entryList(filters, QDir::Files);
    for (const QString &file : files) {
        QString filePath = folder.absoluteFilePath(file);
        QFileInfo fileInfo(filePath);
        if (fileInfo.suffix() == "cpp" || fileInfo.suffix() == "c") {
            QFile inputFile(filePath);
            if (inputFile.open(QIODevice::ReadOnly | QIODevice::Text)) {
                QTextStream in(&inputFile);
                while (!in.atEnd()) {
                    QString line = in.readLine();
                    out << line << "\n";
                }
                inputFile.close();
                cppcCount++;
            }
        }
        else if (fileInfo.suffix() == "h") {
            QFile inputFile(filePath);
            if (inputFile.open(QIODevice::ReadOnly | QIODevice::Text)) {
                QTextStream in(&inputFile);
                while (!in.atEnd()) {
                    QString line = in.readLine();
                    out << line << "\n";
                }
                inputFile.close();
                hCount++;
            }
        }
    }

    QStringList folders = folder.entryList(QDir::Dirs | QDir::NoDotAndDotDot);
    for (const QString &subfolder : folders) {
        processFolder(folder.absoluteFilePath(subfolder), out, cppcCount, hCount, filters);
    }
}

选择好保存路径和代码文件后点击保存/读取文件按钮,出现以下选择框:

选择文件类型后会在左边浏览框里显示文件个数。

3、获取代码行数

//获取代码行数
void ValidCode::getCodeLines()
{
    if(ui->editSaveFile->text().isEmpty()){
        QMessageBox emptyWarnBox;
        emptyWarnBox.warning(nullptr, "Warn", "保存路径为空");
        return;
    }
    QFile file(ui->editSaveFile->text());
    int totalLines = 0;
    int codeLines = 0;
    bool inBlockComment = false;
    QString codeInfo;

    if (file.open(QIODevice::ReadOnly | QIODevice::Text)) {
        QTextStream in(&file);
        while (!in.atEnd()) {
            QString line = in.readLine().trimmed();     //删除行首行尾空格

            if (!line.isEmpty() && !line.startsWith("//") && !inBlockComment) {
                if (!line.startsWith("/*") && !line.endsWith("*/")) {
                    codeLines++;
                }
                else if (line.startsWith("/*")) {
                    inBlockComment = true;
                }
            }

            if (inBlockComment && line.contains("*/")) {
                inBlockComment = false;
            }
            totalLines++;
        }
        file.close();
    }
    codeInfo = "全部代码行数:" + QString::number(totalLines) + "\n有效代码行数:" + QString::number(codeLines);
    ui->browseReadFile->append(codeInfo);
}

把该功能单独用一个按钮实现是想在没有选择代码文件的情况下,也能获取一个txt的代码行数。

4、保留有效代码

//保留有效代码
void ValidCode::retainValidCode()
{
    QMessageBox::StandardButton reply;
    reply = QMessageBox::question(this, "Confirmation", "修改文件仅保留有效代码部分,是否继续?", QMessageBox::Yes|QMessageBox::No);
    if (reply == QMessageBox::No) {
        return;
    }

    QFile file(ui->editSaveFile->text());
    if (!file.open(QIODevice::ReadWrite | QIODevice::Text)) {
        QMessageBox editFileErrorBox;
        editFileErrorBox.critical(nullptr, "Error", "修改文件失败");
        return;
    }

    QTextStream in(&file);
    QStringList fileContent;
    bool inBlockComment = false;

    while (!in.atEnd()) {
        QString line = in.readLine().trimmed();     //删除行首行尾空格

        if (!line.isEmpty() && !line.startsWith("//") && !inBlockComment) {
            if (!line.startsWith("/*") && !line.endsWith("*/")) {
                fileContent.append(line);
            }
            else if (line.startsWith("/*")) {
                inBlockComment = true;
            }
        }

        if (inBlockComment && line.contains("*/")) {
            inBlockComment = false;
        }
    }

    file.resize(0); // 清空文件内容

    QTextStream out(&file);
    for (const QString &line : fileContent) {
        out << line << "\n";
    }

    file.close();

    QMessageBox successBox;
    successBox.information(nullptr, "Success", "保留有效代码成功");
}

在保存路径下仅保留有效代码,再次获取代码行数就是修改后的了。

最后附带下.h文件内容

#ifndef VALIDCODE_H
#define VALIDCODE_H

#include <QWidget>
#include <QDir>
#include <QFile>
#include <QTextStream>
#include <QString>
#include <QDebug>
#include <QFileDialog>
#include <QStandardPaths>
#include <QRegularExpression>
#include <QMessageBox>

QT_BEGIN_NAMESPACE
namespace Ui {
class ValidCode;
}
QT_END_NAMESPACE

class ValidCode : public QWidget
{
    Q_OBJECT

public:
    ValidCode(QWidget *parent = nullptr);
    ~ValidCode();

private:
    Ui::ValidCode *ui;
    void getSavePath();
    void getCodePath();
    void saveReadFile();
    void processFolder(const QString &folderPath, QTextStream &out, int &cppcCount, int &hCount, const QStringList &filters);
    void getCodeLines();
    void retainValidCode();

};
#endif // VALIDCODE_H
  • 7
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值