是否有人熟悉如何解析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();
}
答案 0 :(得分:17)
你去了:
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")
答案 1 :(得分:7)
您正在寻找的是QTextStream课程。它提供了各种用于读写文件的接口。
一个简单的例子:
QStringList firstColumn;
QFile f1("h:/1.txt");
f1.open(QIODevice::ReadOnly);
QTextStream s1(&f1);
while (!s1.atEnd()){
QString s=s1.readLine(); // reads line from file
firstColumn.append(s.split(",").first()); // appends first column to list, ',' is separator
}
f1.close();
或者是的,你可以做类似这样的结果:
wordList = f.readAll().split(QRegExp("[\r\n]"),QString::SkipEmptyParts); //reading file and splitting it by lines
for (int i=0;i<wordList.count();i++)
wordList[i]=wordlist[i].split(",").first(); // replacing whole row with only first value
f.close();
答案 2 :(得分:6)
这是我经常使用的代码。我是作者,考虑这个原样,公共领域。它具有与CodeLurker's code类似的功能集和概念,除了状态机的表示方式不同,代码有点短。
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
,如果是EOF,则返回false
。std::runtime_error
。它解析Excel样式的CSV,适当地处理引号和双引号,并允许字段中的换行符。只要使用QFile::Text
打开文件,就可以正确处理Windows和Unix行结尾。我不认为Qt支持老式的Mac行结尾,并且这不支持二进制模式的非翻译行结尾,但是在大多数情况下,这应该不是问题。
其他说明:
x"y"z
为xyz
,不确定中间字符串引号的规则是什么。我不知道这是否正确。QChar
应该是微不足道的。示例:
QFile csv(filename);
csv.open(QFile::ReadOnly | QFile::Text);
QTextStream in(&csv);
QStringList row;
while (readCSVRow(in, &row))
qDebug() << row;
答案 3 :(得分:5)
有人可能更喜欢这样做:
QStringList MainWindow::parseCSV(const QString &string)
{
enum State {Normal, Quote} state = Normal;
QStringList fields;
QString value;
for (int i = 0; i < string.size(); i++)
{
const QChar current = string.at(i);
// Normal state
if (state == Normal)
{
// Comma
if (current == ',')
{
// Save field
fields.append(value.trimmed());
value.clear();
}
// Double-quote
else if (current == '"')
{
state = Quote;
value += current;
}
// Other character
else
value += current;
}
// In-quote state
else if (state == Quote)
{
// Another double-quote
if (current == '"')
{
if (i < string.size())
{
// A double double-quote?
if (i+1 < string.size() && string.at(i+1) == '"')
{
value += '"';
// Skip a second quote character in a row
i++;
}
else
{
state = Normal;
value += '"';
}
}
}
// Other character
else
value += current;
}
}
if (!value.isEmpty())
fields.append(value.trimmed());
// Quotes are left in until here; so when fields are trimmed, only whitespace outside of
// quotes is removed. The quotes are removed here.
for (int i=0; i<fields.size(); ++i)
if (fields[i].length()>=1 && fields[i].left(1)=='"')
{
fields[i]=fields[i].mid(1);
if (fields[i].length()>=1 && fields[i].right(1)=='"')
fields[i]=fields[i].left(fields[i].length()-1);
}
return fields;
}
编辑:我终于得到了这个来修剪字段之前和之后的空格。引号内没有修剪空格或逗号。否则,从字段的开头和结尾剪切所有空格。在对此进行了一段时间的困惑之后,我想到引号可以留在场地周围;因此可以修剪所有字段。这样,只删除引号之前和之后的空格。然后添加最后一步,去除以引号开头和结尾的字段的引号。
这是一个或多或少具有挑战性的测试案例:
QStringList sl=
{
"\"one\"",
" \" two \"\"\" , \" and a half ",
"three ",
"\t four"
};
for (int i=0; i < sl.size(); ++i)
qDebug() << parseCSV(sl[i]);
这对应于文件
"one"
" two """ , " and a half
three
<TAB> four
其中&lt; TAB&gt;表示制表符;每行依次输入parseCSV()。不要写这样的.csv文件!
它的输出是(其中qDebug()用\"
表示字符串中的引号并将内容放在引号和parens中:
("one")
(" two \"", " and a half")
("three")
("four")
您可以观察到引用和额外空格保留在项目#34; 2&#34;的引号内。在&#34;半&#34;的格式错误的情况下,引用前的空格和最后一个字后的空格被删除;但其他人则没有。此例程中缺少终端空间可能表示缺少终端报价。在不开始或结束它的字段中的引号仅被视为字符串的一部分。如果一个字段没有启动,则不会从字段末尾删除引号。要在此检测错误,只需检查以引号开头但不以一个结尾的字段;和/或包含引号但在最后一个循环中不以一个开头和结尾的一个。
我知道,对于你的测试案例来说,需要的不仅仅是;但是对于这个问题仍然是一个可靠的答案 - 也许对其他人来说也是如此。
答案 4 :(得分:4)
尝试使用qtcsv库来读取和编写csv文件。例如:
#include <QList>
#include <QStringList>
#include <QDir>
#include <QDebug>
#include "qtcsv/stringdata.h"
#include "qtcsv/reader.h"
#include "qtcsv/writer.h"
int main()
{
// prepare data that you want to save to csv-file
QStringList strList;
strList << "one" << "two" << "three";
QtCSV::StringData strData;
strData.addRow(strList);
strData.addEmptyRow();
strData << strList << "this is the last row";
// write to file
QString filePath = QDir::currentPath() + "/test.csv";
QtCSV::Writer::write(filePath, strData);
// read data from file
QList<QStringList> readData = QtCSV::Reader::readToList(filePath);
for ( int i = 0; i < readData.size(); ++i )
{
qDebug() << readData.at(i).join(",");
}
return 0;
}
我试着让它小巧易用。有关库文档和其他代码示例,请参阅Readme文件。
答案 5 :(得分:1)
lines = data.split('\n');
然后
for line in lines
column1.add(line.split(',')[0])
我不确定添加函数是否存在以添加到数组中 - 让我们调用第1列