cocos2dx游戏开发学习——CSV文件解析

在cocos2dx项目中,我们经常会用到CSV文件。这里直接上代码。
ALCsvUtil.h

/**
 *  CSV 解析工具
 */
#ifndef ALCsvUtil_h
#define ALCsvUtil_h

#include <vector>
#include <map>
#include <string>

typedef std::vector<std::string> StrVec;

typedef std::vector< StrVec > StrDict;

typedef std::map< std::string, StrDict> CsvMap;



class ALCsvUtil
{
public:
    static ALCsvUtil* getInstance();
    
    static void destroyInstance();
    
    /**
     *  add csv file to dict
     *
     *  @param sPath is csv file path
     */
    virtual bool addFileData(const std::string &rSCsvFilePath);
    
    /**
     *  del csv file to dict
     *
     *  @param sPath is csv file path
     */
    virtual void releaseFile(const std::string &rSCsvFilePath);
    
    /**
     *  get some row and some column value from some csv file
     *
     *  @param rRow        is row num
     *  @param rCol        is column num
     *  @param csvFilePath is some csv file
     *
     *  @return some row and some column real TextValue IntValue, DoubleValue,if this pos not be exsit return ""
     */
    virtual std::string getText(const int &rRow, const int &rCol, const std::string &rSCsvFilePath);
    virtual int getInt(const int &rRow, const int &rCol, const std::string &rSCsvFilePath);
    virtual double getDouble(const int &rRow, const int &rCol, const std::string &rSCsvFilePath);
    
    /**
     *  get some file row data
     *
     *  @param iRow          is row num
     *  @param rSCsvFilePath is some csv file
     *
     *  @return some row data
     */
    virtual StrVec getRowData(const int &rIRow, const std::string &rSCsvFilePath);
    
    /**
     *  get csv file row and column save tuple<int, int>
     *
     *  @param rSCsvFilePath csv file path
     *
     *  @return csv file row, column in tuple<int, int>
     */
    virtual std::tuple<int, int> getFileRowColNum(const std::string &rSCsvFilePath);
    
    /**
     *  find dest value in csv file row num
     *
     *  @param rSValue       find value
     *  @param rIValueCol    value column
     *  @param rSCsvFilePath csv file path
     *
     *  @return value in csv row
     */
    virtual int findValueInWithLine(const std::string &rSValue, const int &rIValueCol, const std::string &rSCsvFilePath);
    
    
protected:
    /**
     *  get csv file string vec
     *
     *  @param rSCsvFilePath csv file path
     *
     *  @return csv file strVec
     */
    virtual StrDict &getFileDict(const std::string &rSCsvFilePath);
    
    virtual ~ALCsvUtil();
    
    /**
     *  get csv file string vec
     *
     *  @param rSCsvFilePath csv file path
     *
     *  @return csv file strVec
     */
    /**
     get string vec by split

     @param rSSrcStr content
     @param rSSep  Seperator
     @return std::vector<std::string>
     */
    StrVec split(const std::string &rSSrcStr, const char &rSSep);
    
    
private:
    ALCsvUtil();
    
    ALCsvUtil(const ALCsvUtil &rCsvUtil) = delete;
    
    ALCsvUtil &operator=(const ALCsvUtil &rCsvUtil) = delete;
    
    
private:
    static ALCsvUtil* _gInstance;
    
    CsvMap* _pCsvMap;
};

#endif /* ALCsvUtil_h */

ALCsvUtil.cpp

//
//  ALCsvUtil.cpp
//  GameTest-mobile
//
//  Created by Allen on 2018/7/2.
//

#include "ALCsvUtil.h"


ALCsvUtil* ALCsvUtil::_gInstance;

ALCsvUtil::ALCsvUtil():_pCsvMap(nullptr)
{
    _pCsvMap = new CsvMap();
}

ALCsvUtil::~ALCsvUtil()
{
    CC_SAFE_DELETE(_pCsvMap);
}

ALCsvUtil* ALCsvUtil::getInstance()
{
    if (!_gInstance) {
        _gInstance = new ALCsvUtil();
    }
    return _gInstance;
}

void ALCsvUtil::destroyInstance()
{
    if (_gInstance) {
        CC_SAFE_DELETE(_gInstance);
    }
}

bool ALCsvUtil::addFileData(const std::string &rSCsvFilePath)
{
    if (std::string("") == rSCsvFilePath) return false;
    
    
    if (!cocos2d::FileUtils::getInstance()->isFileExist(rSCsvFilePath)) {
        CCLOG("ALCsvUtil::addFileData():  %s file could not be found",rSCsvFilePath.c_str());
        return false;
    }
    cocos2d::Data csvData = cocos2d::FileUtils::getInstance()->getDataFromFile(rSCsvFilePath);
    if (!csvData.getBytes()) {
        CCLOG("ALCsvUtil::addFileData():  %s file is null",rSCsvFilePath.c_str());
        return false;
    }
    StrVec linesVec = split((char*)csvData.getBytes(), '\n');
    StrVec strsVec;
    StrDict dict;
    for (const auto &linesVecIter :linesVec) {
        std::string lineStr(linesVecIter);
        if (lineStr[lineStr.length() - 1] == '\r') {
            lineStr = lineStr.substr(0,lineStr.length() - 1);
        }
        strsVec = split(lineStr, ',');
        dict.push_back(strsVec);
    }
    _pCsvMap->insert(std::make_pair(std::string(rSCsvFilePath), dict));
    return true;
}

void ALCsvUtil::releaseFile(const std::string &rSCsvFilePath)
{
    _pCsvMap->erase(rSCsvFilePath);
}

std::tuple<int,int> ALCsvUtil::getFileRowColNum(const std::string &rSCsvFilePath)
{
    auto dict = getFileDict(rSCsvFilePath);
    int rowNum = (int) dict.size();
    int colNum = (int) (*(dict.begin())).size();
    return std::make_tuple(colNum,rowNum-1);
}

std::string ALCsvUtil::getText(const int &rRow, const int &rCol, const std::string &rSCsvFilePath)
{
    const auto dict = getFileDict(rSCsvFilePath);
    CCASSERT(rRow < dict.size() && rCol < dict.at(rRow).size(), "ALCsvUtil: (row or col) out of range in getObjectAtIndex() ");
    return dict.at(rRow).at(rCol);
}

int ALCsvUtil::getInt(const int &rRow, const int &rCol, const std::string &rSCsvFilePath)
{
    return atoi(getText(rRow, rCol, rSCsvFilePath).c_str());
}

double ALCsvUtil::getDouble(const int &rRow, const int &rCol, const std::string &rSCsvFilePath)
{
    return atof(getText(rRow, rCol, rSCsvFilePath).c_str());
}

StrVec ALCsvUtil::getRowData(const int &rIRow, const std::string &rSCsvFilePath)
{
    auto tRow = std::get<1>(getFileRowColNum(rSCsvFilePath));
    
    if(rIRow > tRow) return StrVec();
    
    return  _pCsvMap->at(rSCsvFilePath).at(rIRow);
}

StrDict &ALCsvUtil::getFileDict(const std::string &rSCsvFilePath)
{
    CCASSERT((_pCsvMap->end() != _pCsvMap->find(rSCsvFilePath) || addFileData(rSCsvFilePath)),"ALCsvUtil: load csvFile file");
    return _pCsvMap->at(rSCsvFilePath);
}

int ALCsvUtil::findValueInWithLine(const std::string &rSValue, const int &rIValueCol, const std::string &rSCsvFilePath)
{
    auto iRowCount = std::get<1>(getFileRowColNum(rSCsvFilePath));
    
    auto ret = -1;
    std::string findValue(rSValue);
    
    for (int iRow = 0; iRow < iRowCount; ++iRow)
    {
        std::string tmpValue = getText(iRow, rIValueCol, rSCsvFilePath);
        if (findValue == tmpValue)
        {
            ret = iRow;
            break;
        }
    }
    return ret;
}

StrVec ALCsvUtil::split(const std::string &rSSrcStr, const char &rSSep)
{
    StrVec strList;
    
    std::string::size_type lastIndex = rSSrcStr.find_first_not_of(rSSep,0);
    std::string::size_type currentIndex = rSSrcStr.find_first_of(rSSep,lastIndex);
    while (std::string::npos != currentIndex || std::string::npos != lastIndex)
    {
        strList.push_back(rSSrcStr.substr(lastIndex,currentIndex - lastIndex));
        lastIndex = rSSrcStr.find_first_not_of(rSSep,currentIndex);
        currentIndex = rSSrcStr.find_first_of(rSSep,lastIndex);
    }
    
    return strList;
}

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,496评论 6 501
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,407评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,632评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,180评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,198评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,165评论 1 299
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,052评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,910评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,324评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,542评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,711评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,424评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,017评论 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,668评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,823评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,722评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,611评论 2 353

推荐阅读更多精彩内容