c++解析csv文件

针对unix跟windows平台,换行符不同,造成的问题,对csv解析进行了一些修改。。。



/**
* 解析完的数据放到data这个二维数组中,通过getData(int rows,int cols)
* 获取数据
**/

#ifndef _CSVPARSE_
#define _CSVPARSE_

#include "cocos2d.h"
#include <stdio.h>
#include <iostream>
#include <fstream>

class CSVParse {

public:
CSVParse(istream& fin = cin, string sep = ","):
fieldsep(sep),
cols(0)
{}
~CSVParse();
private:
string fieldsep; // separator characters
vector<vector<string> > data;
int cols;

private:
void split(vector<string>& field,string line);
int advplain(const string& line, string& fld, int);
int advquoted(const string& line, string& fld, int);

public:
//打开文件
bool openFile(const char* fileName);
bool openFile2(const char* fileName);
//根据行列获取数据
const char* getData(int rows,int cols);
//该列是否有此数据
int findColsData(int cols,const char* value);
//得到最大的列数
inline int getCols(){return cols;}
//得到总共的行数
inline int getRows(){return data.size();}
};

#endif
#endif




#include "CSVParse.h"

using namespace cocos2d;


CSVParse::~CSVParse()
{
for (int i=0; i<data.size(); i++) {
data[i].clear();
}
data.clear();
}

// split: split line into fields
void CSVParse::split(vector<string>& field,string line)
{
string fld;
int i, j;

if (line.length() == 0)
return ;
i = 0;

do {
if (i < line.length() && line[i] == '"')
j = advquoted(line, fld, ++i); // skip quote
else
j = advplain(line, fld, i);

field.push_back(fld);
i = j + 1;
} while (j < line.length());

}

// advquoted: quoted field; return index of next separator
int CSVParse::advquoted(const string& s, string& fld, int i)
{
int j;

fld = "";
for (j = i; j < s.length(); j++)
{
if (s[j] == '"' && s[++j] != '"')
{
int k = s.find_first_of(fieldsep, j);
if (k > s.length()) // no separator found
k = s.length();
for (k -= j; k-- > 0; )
fld += s[j++];
break;
}
fld += s[j];
}
return j;
}

// advplain: unquoted field; return index of next separator
int CSVParse::advplain(const string& s, string& fld, int i)
{
int j;

j = s.find_first_of(fieldsep, i); // look for separator
if (j > s.length()) // none found
j = s.length();
fld = string(s, i, j-i);
return j;
}


// getfield: return n-th field
const char* CSVParse::getData(int rows,int cols)
{
if (rows<0||rows>=data.size()||cols<0||cols>=data[rows].size()) {
return "";
}

return data[rows][cols].c_str();
}

int CSVParse::findColsData(int cols,const char* value)
{
for (int i=0; i<data.size(); i++) {
if (strcmp(getData(i, cols), value)==0 )
{
return i;
}
}
return -1;
}
//用于兼容windows下的换行符\r\n
//原因是在windows下换行符为\r\n,而在unix下则为\n
//进行封装,否则读取的每行读取的最后一个数据默认会有个额外的\r
bool getline(std::ifstream &is,std::string &str){
bool b = std::getline(is,str);
std::string::size_type p = str.find_last_of('\r');
if(p != std::string::npos) str.erase(p);
return b;
}

//读取方式: 逐行读取, 将行读入字符串, 行之间用回车换行区分
//If you want to avoid reading into character arrays,
//you can use the C++ string getline() function to read lines into strings
bool CSVParse::openFile(const char* fileName)
{
string pathKey = CCFileUtils::fullPathFromRelativePath(fileName);
ifstream fin(pathKey.c_str());
string s;

while(::getline(fin,s))
{
CCLOG("%s",s.c_str());
vector<string> field;
split(field,s);
data.push_back(field);
cols=max(cols, (int)field.size());
}

for (int i=0; i<data.size(); i++) {
for (int k=0; k<data[i].size(); k++) {
CCLOG("%s",getData(i, k));
}

}

return true;
}

//该方法可用于anroid跟ios及windows平台

bool CSVParse::openFile2(const char* fileName)
{

const char* xmlConfFullPath = CCFileUtils::fullPathFromRelativePath(fileName);

CCFileData csvdata(xmlConfFullPath, "rt");
unsigned long size = csvdata.getSize();

char *pBuffer = (char*) csvdata.getBuffer();

string stringData(pBuffer);

stringstream strm;

strm.write(pBuffer, size);


string s;

while(::getline(fin,s))
{
CCLOG("%s",s.c_str());
vector<string> field;
split(field,s);
data.push_back(field);
cols=max(cols, (int)field.size());
}

for (int i=0; i<data.size(); i++) {
for (int k=0; k<data[i].size(); k++) {
CCLOG("%s",getData(i, k));
}

}

return true;
}


参考:http://www.cnblogs.com/JCSU/articles/1190685.html
http://www.cnblogs.com/huoguofeng/archive/2010/11/24/1887087.html
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值