有能力补充修正的请进,这几天脑子乱的。。。。
我发现分割 字符的确是件很了不起的工程。。。。多个引号或分割符(,)还是会有些错误,还待进一步修正
QStringList DBBrowserDB::decodeCSV(const QString & csvfilename, char sep, char quote, int maxrecords, int * numfields)
{
QFile file(csvfilename);
QStringList curList;
bool inita = false;
bool initc = false;
int recs = 0;
*numfields = 0;
if(file.open(QIODevice::ReadOnly))
{
QTextStream fin(&file);
QString text_str,current;
while(!fin.atEnd())
{
text_str=fin.readLine();
int my_size,i_a=0;
my_size=text_str.size();
while(i_a<my_size)
{
if(text_str.at(i_a)==quote && inita==false)
{
inita=true;
}
if(text_str.at(i_a)==quote && inita==true)
{
if(i_a<my_size-1)
{
if(text_str.at(i_a+1)==sep)
{
curList.append(current);
inita=false;
current.clear();
}else
{
if(text_str.at(i_a+1)==quote)
{
current.append(text_str.at(i_a));
inita=false;
i_a++;
}
}
}
}
if(text_str.at(i_a)!=quote)
{
if(text_str.at(i_a)==sep && i_a>0)
{
if(text_str.at(i_a-1)==quote)
{
if(current.size()!=0)
{
curList.append(current);
inita=false;
current.clear();
}
}
if(inita==false && current.size()>0)
{
curList.append(current);
current.clear();
}
if(inita==true)
{
current.append(sep);
}
}
else
{
current.append(text_str.at(i_a));
}
}
if(i_a==my_size-2 && text_str.at(i_a+1)==quote)
{
curList.append(current);
inita=false;
current.clear();
}
if(i_a==my_size-1 && text_str.at(i_a)!=quote)
{
curList.append(current);
inita=false;
current.clear();
}
qDebug()<<current;
qDebug()<<curList;
i_a++;
}
if(initc==false)
{
initc=true;
*numfields=curList.count();
}
recs++;
if(maxrecords==recs || maxrecords==*numfields)
{break;}
}
}
file.close();
return curList;
curList.clear();
}
[ 本帖最后由 haulm 于 2011-2-12 10:45 编辑 ] 还是用python吧,哈哈,从来不烦恼
>>> ttt ="aa,bb,cc"
>>> ttt.split(',')
['aa', 'bb', 'cc'] 手写的 csv 分析器,最好有状态图表示吧,这个很难看懂的... 另外就是 Qt 的 QString 有分割函数的
split()
section()
left()
mid()
right() QStrings的分割很好用啊。为什么要自己写啊。 几位兄台,如果能直接用 splite 分割就不用想破头了。。。
我要实现的是 excel 对 CSV 文件的分析,CSV 文件的分割遇到特殊文本会用引号区分再用逗号隔开,但是遇到正常文本的表格就直接用逗号隔开。
这里就出现了“xxx”,"""""",",,,"等。。。
如果直接用 splite 分割你觉得能得到什么正确的结果?
比如一个 CSV 数字描述
1,000 1,000,这个存成 CVS( 逗号) 就出是 1“,”000,1","000
那你直接用 splite怎么分割?
原帖由 nihui 于 2011-2-11 14:39 发表 http://www.linuxfans.org/bbs/images/common/back.gif
另外就是 Qt 的 QString 有分割函数的
split()
section()
left()
mid()
right()
mid() splite() 有用过,遇到困难,最后只能是一个个字符老老实实分析,section() 没用过,left() right() 在这里不好用。
[ 本帖最后由 haulm 于 2011-2-11 21:51 编辑 ] 看了一下 section() ,还是这个好用,这样的话我可以直接对文本分析后直接处理掉。 https://github.com/nihui/oxygenspread/blob/master/file_csv.c
以前学win32编程做的表格,纯C的,但愿你能看懂吧。。:? 原帖由 haulm 于 2011-2-11 21:43 发表 http://www.linuxfans.org/bbs/images/common/back.gif
几位兄台,如果能直接用 splite 分割就不用想破头了。。。
我要实现的是 excel 对 CSV 文件的分析,CSV 文件的分割遇到特殊文本会用引号区分再用逗号隔开,但是遇到正常文本的表格就直接用逗号隔开。
这里就出现了“xxx”, ...
只要c能处理,qstrings肯定能处理,再说qt还有qregexp,肯定比c要方便的。 原帖由 sejishikong 于 2011-2-12 09:43 发表 http://www.linuxfans.org/bbs/images/common/back.gif
只要c能处理,qstrings肯定能处理,再说qt还有qregexp,肯定比c要方便的。
我也都写好了,只不过有时出现段错误,比如遇到重复的一堆引号和逗号相加杂的,qDebug 分析不到什么,更麻烦的是
不知道 office 为何在处理 CVS ", 这两个左可相连的符号时用了更多的引号?
这种程序看似简单,实际上没法把这种简单的抽象任务一下就写成程序,只能一点点调试和分析错误。
用 QString 的原因是因为可以按编码进行分析,用 char * 就遇到半字问题了。
本来想写注解的,后来发现没完成之前,注解都没法写清楚。
[ 本帖最后由 haulm 于 2011-2-12 10:48 编辑 ] 一个参考:http://sourceforge.net/projects/qcsv/
我没仔细看,不过大体思路这个就行,顶多是regexp需要调整。 以下定义译自 wikipedia 上的 CSV 篇目
每行记录由 \n 或者 \r\n 分隔,但是字段内嵌的 \n 或 \r\n 不算
每条字段由 , 分隔
如果字段中内嵌 , ,需要使用 " 括起这条字段
如果字段中内嵌 \n 或 \r\n ,需要使用 " 括起这条字段
如果字段中内嵌 " ,需要在该 " 前面再添加 " 转义
字段前后的空白需要保留
如果字段中没有内嵌 , 或 \n 或 \r\n 或 ",可以使用 " 括起这条字段,也可以不使用
第一行记录可能包含字段的属性名称
我的分析器遇到内容有,号,有时会出错,正在下载那个项目看看。
[ 本帖最后由 haulm 于 2011-2-12 12:14 编辑 ] 原帖由 nihui 于 2011-2-12 11:51 发表 http://www.linuxfans.org/bbs/images/common/back.gif
以下定义译自 wikipedia 上的 CSV 篇目
实现起来就没有描述的那么简单了。 原帖由 haulm 于 2011-2-12 12:18 发表 http://www.linuxfans.org/bbs/images/common/back.gif
实现起来就没有描述的那么简单了。
给个分析器的流程,这样应该不难了。
dq表示双引号,sep表示分隔符逗号,lf表示换行和回车
stateA: closed-dq
stateB: opening-dq
stateC: opening-dq+dq(?) / closed-dq
初始stateA
读入字符c,直到eof
c为dq
stateA: -> stateB
stateB: -> stateC
stateC: dq 存入 field,-> stateA
c为sep
stateA/C: field 存入 record,-> stateA
stateB: sep 存入 field
c为lf
stateA/C: field 存入 record,record 存入 table,-> stateA
stateB: lf 存入 field
其它
stateA/C: c 存入 field,-> stateA
stateB: c 存入 field
[ 本帖最后由 nihui 于 2011-2-12 14:37 编辑 ]
页:
[1]
2