欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 科技 > IT业 > Qt解析复杂的csv格式文件

Qt解析复杂的csv格式文件

2024/10/24 4:30:39 来源:https://blog.csdn.net/c1s2d3n4cs/article/details/140518430  浏览:    关键词:Qt解析复杂的csv格式文件

/*csv格式是以逗号分隔列的。
* 每行内容是以换行符作为一行的。
* 如果内容中包含换行符,则整个内容要以双引号括起来。
* 如果内容中包含逗号,则整个内容要以双引号括起来。
* 如果内容中又有双引号,则会是2个双引号连在一起表示一个双引号。
* 每个字段的左右2边的空白字符可以忽略。
* 还有其他复杂的情况,暂时不考虑
*/
/*针对以上csv的复杂多变的格式,我们这里只考虑以下几种情况吧:
* 1. 逗号分隔列。
* 2. 某个列的内容可能多行显示。
* 3. 某个列可能存在逗号、双引号、换行。
*/

QList<QStringList> parseCSVFile(const QString &strFile)
{QList<QStringList> allRecordSets;QFile file(strFile);if (!file.open(QFile::ReadOnly)) return allRecordSets;QTextStream ins(&file);bool bInQuote = false;const QChar chQuote('\"');const QChar chEnter('\n');const QChar chComma(',');int iFileLineCount = 0;QStringList currentRecordset;QString strFieldData;while (!ins.atEnd()){++iFileLineCount;const QString strLine = ins.readLine()+'\n'; //QTextStream::readLine()去掉了换行符for (int i=0; i<strLine.size(); ++i){const QChar c = strLine.at(i);if (chComma == c){if (bInQuote){strFieldData.append(c);}else{strFieldData = strFieldData.trimmed(); //去掉左右两边的空白字符currentRecordset.append(strFieldData);strFieldData = "";}}else if (chEnter == c){if (bInQuote){strFieldData.append(c);}else{strFieldData = strFieldData.trimmed(); //去掉左右两边的空白字符currentRecordset.append(strFieldData);allRecordSets.append(currentRecordset);strFieldData = "";currentRecordset.clear();}}else if (chQuote == c){//由于strLine的最后一个字符一定是'\n',所以strLine.at(i+1)肯定不会越界,所以无需判断越界。if (bInQuote){//当前字符是双引号,且最开始已经有双引号,则当前字符可能是字段内容,也可能是字段结束位置QChar next = strLine.at(i+1);if (chQuote == next){//当前字符的下一个字符是双引号,说明是字段内容的一部分strFieldData.append(c);++i;}else if (chEnter == next){//当前字符的下一个字符是换行,说明当前的一条记录解析完毕bInQuote = false;}else if (chComma == next){//当前字符的下一个字符是逗号,说明当前字段解析完毕bInQuote = false;}else if (next.isSpace()){//双引号结束的情况下,如果当前字符的下一个字符是空白字符,则忽略for(++i;i<strLine.size();){next = strLine.at(i);if (next.isSpace() && next!=chEnter){//是空白字符但不是换行++i;}else{--i; //便于下一个解析,所以指针回退。break;}}bInQuote = false;}else{//说明格式有问题qDebug().noquote().nospace()<<QString("the csv file(%1)(line=%2) has format error").arg(strFile).arg(iFileLineCount);strFieldData.append(c);}}else{//表示字段的开始bInQuote = true;}}else{strFieldData.append(c);}}}return allRecordSets;
}

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com