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); //根据行列获取数据 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 fieldsvoid 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 separatorint 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 separatorint 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 fieldconst 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//进行封装,否则读取的每行读取的最后一个数据默认会有个额外的\rbool 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 stringsbool 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;}
参考:http://www.cnblogs.com/JCSU/articles/1190685.html
http://www.cnblogs.com/huoguofeng/archive/2010/11/24/1887087.html