cocos2dx游戲開發(fā)學(xué)習(xí)——CSV文件解析

在cocos2dx項(xiàng)目中堪遂,我們經(jīng)常會(huì)用到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;
}

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子吞加,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,214評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件衔憨,死亡現(xiàn)場(chǎng)離奇詭異叶圃,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)践图,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,307評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門掺冠,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人码党,你說我怎么就攤上這事德崭。” “怎么了揖盘?”我有些...
    開封第一講書人閱讀 152,543評(píng)論 0 341
  • 文/不壞的土叔 我叫張陵眉厨,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我扣讼,道長(zhǎng)缺猛,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,221評(píng)論 1 279
  • 正文 為了忘掉前任椭符,我火速辦了婚禮荔燎,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘销钝。我一直安慰自己有咨,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,224評(píng)論 5 371
  • 文/花漫 我一把揭開白布蒸健。 她就那樣靜靜地躺著座享,像睡著了一般。 火紅的嫁衣襯著肌膚如雪似忧。 梳的紋絲不亂的頭發(fā)上渣叛,一...
    開封第一講書人閱讀 49,007評(píng)論 1 284
  • 那天,我揣著相機(jī)與錄音盯捌,去河邊找鬼淳衙。 笑死,一個(gè)胖子當(dāng)著我的面吹牛饺著,可吹牛的內(nèi)容都是我干的箫攀。 我是一名探鬼主播,決...
    沈念sama閱讀 38,313評(píng)論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼幼衰,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼靴跛!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起渡嚣,我...
    開封第一講書人閱讀 36,956評(píng)論 0 259
  • 序言:老撾萬榮一對(duì)情侶失蹤梢睛,失蹤者是張志新(化名)和其女友劉穎肥印,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體绝葡,經(jīng)...
    沈念sama閱讀 43,441評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡竖独,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,925評(píng)論 2 323
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了挤牛。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,018評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡种蘸,死狀恐怖墓赴,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情航瞭,我是刑警寧澤诫硕,帶...
    沈念sama閱讀 33,685評(píng)論 4 322
  • 正文 年R本政府宣布,位于F島的核電站刊侯,受9級(jí)特大地震影響章办,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜滨彻,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,234評(píng)論 3 307
  • 文/蒙蒙 一藕届、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧亭饵,春花似錦休偶、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,240評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至八秃,卻和暖如春碱妆,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背昔驱。 一陣腳步聲響...
    開封第一講書人閱讀 31,464評(píng)論 1 261
  • 我被黑心中介騙來泰國打工疹尾, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人舍悯。 一個(gè)月前我還...
    沈念sama閱讀 45,467評(píng)論 2 352
  • 正文 我出身青樓航棱,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國和親萌衬。 傳聞我的和親對(duì)象是個(gè)殘疾皇子饮醇,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,762評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容