读书人

c++解析csv资料

发布时间: 2012-08-09 15:59:21 作者: rapoo

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

读书人网 >C++

热点推荐