• [cocos2dx utils] cocos2dx读取,解析csv文件


    在我们的游戏中,经常需要将策划的数值配置成csv文件,所以解析csv文件就是一个很common的logic,

    例如如下csv文件:

    下面是一个基于cocos2dx 2.2.4的实现类:

    #ifndef __Cell__GCCsvHelper__
    #define __Cell__GCCsvHelper__
    
    #include <iostream>
    #include "cocos2d.h"
    #include <vector>
    
    USING_NS_CC;
    
    class GCCsvHelper
    {
    public:
        GCCsvHelper();
        ~GCCsvHelper();
        
        bool openAndResolveFile(const char *fileName);
        
        const char *getData(unsigned int rowIndex, unsigned int colIndex);
        
        inline int getColLength() { return m_colLength; }
        inline int getRowLength() {    return data.size(); }
    
    private:
        const std::string m_seperator;
        std::vector<std::vector<std::string> > data;
        
        //cols length
        int m_colLength;
        
        void rowSplit(std::vector<std::string> &rows, const std::string &content, const char &rowSeperator);
        void fieldSplit(std::vector<std::string> &fields, std::string line);
        
        //获取带引号的字段
        int getFieldWithQuoted(const std::string &line, std::string& field, int index);
        
        //获取无引号的字段
        int getFieldNoQuoted(const std::string &line, std::string &field, int index);
    };
    
    #endif /* defined(__Cell__GCCsvHelper__) */
    #include "GCCsvHelper.h"
    
    GCCsvHelper::GCCsvHelper()
    :m_seperator(",")
    ,m_colLength(0)
    {
        
    }
    
    GCCsvHelper::~GCCsvHelper()
    {
        
    }
    
    #pragma region reselove the content begin...
    
    bool GCCsvHelper::openAndResolveFile(const char *fileName)
    {
        std::string pathKey = CCFileUtils::sharedFileUtils()->fullPathForFilename(fileName);
        unsigned char* pBuffer = NULL;
        unsigned long bufferSize = 0;
        pBuffer = CCFileUtils::sharedFileUtils()->getFileData(pathKey.c_str(), "r", &bufferSize);
        
        std::string tmpStr = (char*)pBuffer;
        std::string fileContent = tmpStr.substr(0, bufferSize);
        
        std::vector<std::string> line;
        rowSplit(line, fileContent, '
    ');
        for (unsigned int i = 0; i < line.size(); ++i) {
            std::vector<std::string> fieldVector;
            fieldSplit(fieldVector, line[i]);
            data.push_back(fieldVector);
            m_colLength = std::max(m_colLength, (int)fieldVector.size());
        }
        
        return true;
    }
    
    
    void GCCsvHelper::rowSplit(std::vector<std::string> &rows, const std::string &content, const char &rowSeperator)
    {
        std::string::size_type lastIndex = content.find_first_not_of(rowSeperator, 0);
        std::string::size_type    currentIndex = content.find_first_of(rowSeperator,lastIndex);
        
        while (std::string::npos != currentIndex || std::string::npos != lastIndex) {
            rows.push_back(content.substr(lastIndex, currentIndex - lastIndex));
            lastIndex = content.find_first_not_of(rowSeperator, currentIndex);
            currentIndex = content.find_first_of(rowSeperator, lastIndex);
        }
    }
    
    void GCCsvHelper::fieldSplit(std::vector<std::string> &fields, std::string line)
    {
        if (line[line.length() - 1] == '
    ') {
            line = line.substr(0, line.length() - 1);
        }
        
        std::string field;
        unsigned int i = 0, j = 0;
        while (j < line.length()) {
            if (line[i] == '"') {
                //有引号
                j = getFieldWithQuoted(line, field, i);
            } else {
                j = getFieldNoQuoted(line, field, i);
            }
            
            fields.push_back(field);
            i = j + 1; //解析下一个field, +1为了跳过当前的分隔符
        }
    }
    
    int GCCsvHelper::getFieldWithQuoted(const std::string &line, std::string &field, int i)
    {
        unsigned int j = 0;
        field = std::string();
        if (line[i] != '"') {
            //不是引号起始,有问题
            CCLOGERROR("start char is not quote when call %s", __FUNCTION__);
            return -1;
        }
        
        for (j = i + 1; j < line.length() - 1; ++j) {
            if (line[j] != '"') {
                //当前char不为引号,则是field内容(包括逗号)
                field += line[j];
            } else {
                //遇到field结束时的引号,可以返回
                return j;
                break;
            }
        }
        
        if (j == line.length()) {
            //没有找到成对的结束引号
            CCLOGERROR("resoleve the line error: no pair quote, line:%s, field:%s, start index:%d", line.c_str(), field.c_str(), i);
        }
        
        return j;
    }
    
    int GCCsvHelper::getFieldNoQuoted(const std::string &line, std::string &field, int index)
    {
        unsigned int j = 0;
        //找到下一个分隔符位置
        j = line.find_first_of(m_seperator, index);
        if (j > line.length()) {
            j = line.length();
        }
        
        field = std::string(line, index, j - index);
        
        return j;
    }
    
    #pragma region end.
    
    ///////search data
    const char *GCCsvHelper::getData(unsigned int rowIndex, unsigned int colIndex)
    {
        if (rowIndex >= getRowLength() || colIndex >= getColLength()) {
            return "";
        }
        
        if (colIndex >= data[rowIndex].size()) {
            return "";
        }
        
        return data[rowIndex][colIndex].c_str();
    }

    Test Case:

    void CsvHelperTesterScene::onEnter()
    {
        CCSize visibleSize = CCDirector::sharedDirector()->getVisibleSize();
        
        GCCsvHelper *csv = new GCCsvHelper();
        csv->openAndResolveFile("test.csv");
        
        std::string line = "";
        for (int i = 0; i < csv->getRowLength(); ++i) {
            for (int j = 0; j < csv->getColLength(); ++j) {
                line += csv->getData(i, j);
                line += ";";
            }
            
            CCLabelTTF *pLbl = CCLabelTTF::create(line.c_str(), "Arial", 20);
            pLbl->setColor(ccc3(255, 250, 250));
            pLbl->setPosition(ccp(visibleSize.width / 2, visibleSize.height - 200 - i * 30));
            addChild(pLbl);
            
            line = "";
        }
        
        delete csv;
    }

    测试结果:

  • 相关阅读:
    平时工作需要用到的adb命令(二)
    计算Android总的内存使用率、CPU使用率和CPU实时主频率
    使用ADB命令写Android自动化测试脚本
    adb常见命令
    Jmeter的安装配置
    SQL Server优化之SQL语句优化
    单例模式——懒汉模式,饿汉模式
    GIT和SVN的区别(面试)
    python zipfile文件名乱码问题
    企业微信给用户发送消息
  • 原文地址:https://www.cnblogs.com/StanBlogs/p/cocos2dx-csvhelper.html
Copyright © 2020-2023  润新知