通过 Qt 中的 csv 文件进行解析

新手上路,请多包涵

是否有人熟悉如何解析 csv 文件并将其放入字符串列表中。现在我将整个 csv 文件放入字符串列表中。我想弄清楚是否有办法只获得第一列。

 #include "searchwindow.h"
#include <QtGui/QApplication>

#include <QApplication>
#include <QStringList>
#include <QLineEdit>
#include <QCompleter>
#include <QHBoxLayout>
#include <QWidget>
#include <QLabel>

#include <qfile.h>
#include <QTextStream>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);

    QWidget *widget = new QWidget();
    QHBoxLayout *layout = new QHBoxLayout();

    QStringList wordList;

    QFile f("FlightParam.csv");
    if (f.open(QIODevice::ReadOnly))
    {
        //file opened successfully
        QString data;
        data = f.readAll();
        wordList = data.split(',');

        f.close();
    }

    QLabel *label = new QLabel("Select");
    QLineEdit *lineEdit = new QLineEdit;
    label->setBuddy(lineEdit);

    QCompleter *completer = new QCompleter(wordList);
    completer->setCaseSensitivity(Qt::CaseInsensitive); //Make caseInsensitive selection

    lineEdit->setCompleter(completer);

    layout->addWidget(label);
    layout->addWidget(lineEdit);

    widget->setLayout(layout);
    widget->showMaximized();

    return a.exec();
}

原文由 user3878223 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 1.4k
2 个回答

你去:

飞行参数.csv

 1,2,3,
4,5,6,
7,8,9,

主文件

#include <QFile>
#include <QStringList>
#include <QDebug>

int main()
{
    QFile file("FlightParam.csv");
    if (!file.open(QIODevice::ReadOnly)) {
        qDebug() << file.errorString();
        return 1;
    }

    QStringList wordList;
    while (!file.atEnd()) {
        QByteArray line = file.readLine();
        wordList.append(line.split(',').first());
    }

    qDebug() << wordList;

    return 0;
}

主程序

TEMPLATE = app
TARGET = main
QT = core
SOURCES += main.cpp

构建并运行

qmake && make && ./main

输出

("1", "4", "7")

原文由 László Papp 发布,翻译遵循 CC BY-SA 3.0 许可协议

这是我通常使用的代码。我是作者,请按原样考虑,公共领域。它与 CodeLurker 的代码 具有相似的功能集和概念,只是状态机的表示方式不同,代码更短一些。

 bool readCSVRow (QTextStream &in, QStringList *row) {

    static const int delta[][5] = {
        //  ,    "   \n    ?  eof
        {   1,   2,  -1,   0,  -1  }, // 0: parsing (store char)
        {   1,   2,  -1,   0,  -1  }, // 1: parsing (store column)
        {   3,   4,   3,   3,  -2  }, // 2: quote entered (no-op)
        {   3,   4,   3,   3,  -2  }, // 3: parsing inside quotes (store char)
        {   1,   3,  -1,   0,  -1  }, // 4: quote exited (no-op)
        // -1: end of row, store column, success
        // -2: eof inside quotes
    };

    row->clear();

    if (in.atEnd())
        return false;

    int state = 0, t;
    char ch;
    QString cell;

    while (state >= 0) {

        if (in.atEnd())
            t = 4;
        else {
            in >> ch;
            if (ch == ',') t = 0;
            else if (ch == '\"') t = 1;
            else if (ch == '\n') t = 2;
            else t = 3;
        }

        state = delta[state][t];

        switch (state) {
        case 0:
        case 3:
            cell += ch;
            break;
        case -1:
        case 1:
            row->append(cell);
            cell = "";
            break;
        }

    }

    if (state == -2)
        throw runtime_error("End-of-file found while inside quotes.");

    return true;

}

  • 参数: in ,一个 QTextStream
  • 参数: row ,一个 QStringList 将接收该行。
  • 返回: true 如果读取了一行, false 如果 EOF。
  • 抛出: std::runtime_error 如果发生错误。

它解析 Excel 样式的 CSV,适当地处理引号和双引号,并允许字段中的换行符。只要使用 QFile::Text 打开文件,就可以正确处理 Windows 和 Unix 行尾。我不认为 Qt 支持老式的 Mac 行尾,而且它不支持二进制模式未翻译的行尾,但在大多数情况下,这在现在应该不是问题。

其他注意事项:

  • 与 CodeLurker 的实现不同,如果 EOF 在引号内被击中,这会故意失败。如果您将状态表中的 -2 更改为 -1,那么它将是宽容的。
  • x"y"z 解析为 xyz ,不确定字符串中引号的规则是什么。我不知道这是否正确。
  • 性能和内存特性与 CodeLurker 的相同(即非常好)。
  • 不支持 unicode( 转换为 ISO-5589-1 )但更改为 QChar 应该是微不足道的。

例子:

 QFile csv(filename);
csv.open(QFile::ReadOnly | QFile::Text);

QTextStream in(&csv);
QStringList row;
while (readCSVRow(in, &row))
    qDebug() << row;

原文由 Jason C 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题