cocos2d-x学习笔记——Csv文件读取工具

cocos2d-x学习笔记——Csv文件读取工具,第1张

概述在一个游戏中,通常会有很多怪物,以及怪物的生命值,魔法值等属性数据,这些数据不可能在代码里面写死,一般都会用配置文件来保存,使用时再加载到内存。 我们常用的配置文件是CSV文件,即逗号分隔值(Comma-Separated Values),如下图所示。 今天,我就来介绍一个来读取CSV文件的工具类——MyCsvUtil。 在接受读取CSV文件工具类之前,先介绍一个读取字符串的工具类——String

在一个游戏中,通常会有很多怪物,以及怪物的生命值,魔法值等属性数据,这些数据不可能在代码里面写死,一般都会用配置文件来保存,使用时再加载到内存。
我们常用的配置文件是CSV文件,即逗号分隔值(Comma-Separated Values),如下图所示。

今天,我就来介绍一个来读取CSV文件的工具类——MyCsvUtil。

在接受读取CSV文件工具类之前,先介绍一个读取字符串的工具类——StringUtil。

//头文件StringUtil.h#ifndef __StringUtil_H_#define __StringUtil_H_#include "cocos2d.h"class StringUtil : public cocos2d::Ref{public:    static StringUtil * getInstance();    virtual bool init();    //用分隔符分割字符窜,结果存放到一个列表中,列表中的对象为Value    cocos2d::ValueVector split(const char * srcStr,const char * sSep);private:    static StringUtil * m_StringUtil;//Util 是工具的意思!};//函数实现文件#include "StringUtil.h"USING_NS_CC;//初始化StringUtil * StringUtil::m_StringUtil = nullptr;StringUtil * StringUtil::getInstance(){    if (m_StringUtil == nullptr)    {        m_StringUtil = new StringUtil();        if (m_StringUtil && m_StringUtil->init() )        {            m_StringUtil->autorelease();            m_StringUtil->retain();        }        else        {            CC_SAFE_DELETE(m_StringUtil);            m_StringUtil = nullptr;        }    }    return m_StringUtil;}bool StringUtil::init(){    ////拆分字符串    //auto strsList = StringUtil::getInstance()->split("zhaolong,want,to,work!",",");    //for (auto str : strsList)    //{    // log("str = %s",str.asstring().c_str());    //}    return true;}//分离函数,srcStr是要进行分离的字符串,sSep是分隔符 separatorValueVector StringUtil::split(const char * srcStr,const char * sSep){    ValueVector stringList; //typedef std::vector<Value> ValueVector;    int size = strlen(srcStr);    //将数据转换为字符串对象    Value str = Value(srcStr);    int startIndex = 0;    int endindex = 0;    endindex = str.asstring().find(sSep);    std::string linestr;    //根据分隔符拆分字符串,并添加到列表中    while (endindex > 0)    {        //拆分的字符串        //substr函数的作用是从给定的字符表达式或备注字段中返回一个子字符串。        linestr = str.asstring().substr(startIndex,endindex);        //放入列表中        stringList.push_back(Value(linestr));        //更新要分离的字符串        str = Value(str.asstring().substr(endindex + 1,size));        //更新索引号        endindex = str.asstring().find(sSep);    }    //剩下的字符串也添加进入列表    //将剩下的字符串与空字符串相比,若不为空    if (str.asstring().compare("") != 0)    {        //就把该字符串放入到列表中        stringList.push_back(Value(str.asstring()));    }    return stringList;}#endif

上面那个字符串工具类,最主要的就是一个split函数,因为已经写了足够多的注释了,这里就不再多做解释了。以后要进行字符串读取的话只需要将这个头文件包含进去,再调用split函数就行了。

下面开始讲解真正的Csv文件读取类

我们要想更好的处理和保存csv文件数据,我们应该把它当作对象来处理,新建一个CsvData类,他的类对象就代表一份Csv文件数据。

//头文件CsvData.h#ifndef __CsvData_H_#define __CsvData_H_#include "cocos2d.h"class CsvData : public  cocos2d::Ref{public:    CREATE_FUNC(CsvData);    virtual bool init();    //添加一行数据    voID addlineData(cocos2d::ValueVector lineData);    //获取某行的数据    cocos2d::ValueVector getSinglelineData(int iline);    //获取行列大小    cocos2d::Size getRowColNum();private:    //用来存放Csv文件所有行的数据    cocos2d::ValueVector m_alllinesVec;};//函数实现文件#include "CsvData.h"USING_NS_CC;bool CsvData::init(){    return true;}voID CsvData::addlineData(ValueVector lineData){    m_alllinesVec.push_back(Value(lineData));}ValueVector CsvData::getSinglelineData(int iline){    return m_alllinesVec.at(iline).asValueVector();}Size CsvData::getRowColNum(){    Size size = Size();    //获得Csv文件的行数,因为m_alllinesVec变量保存的就是每一行的数据,所以m_alllinesVec的大小就是行的数量    size.wIDth = m_alllinesVec.size();    //如果Csv文件中的行数大于0    if (size.wIDth > 0)    {        //就求Csv文件第0行的数据的个数,得到列的数量        size.height = m_alllinesVec.at(0).asValueVector().size();    }    return size;}#endif

这个CsvData类比较简单,不必多说了,只需要注意的是getRowColNum这个函数。这个函数是获取Csv文件的规模,即行数和列数(行号和列号都是从0开始的)。
因为Csv文件保存的就是每一行的数据,所以Csv的size大小就是行的数量,要求列数的话,就求Csv文件第0行的数据的个数,得到列的数量。

然后,然后就是真正的编写Csv文件读取工具类啦!

//头文件MyCsvUtil.h#ifndef __MyCsvUtil_H_#define __MyCsvUtil_H_#include "CsvData.h"class MyCsvUtil : public cocos2d::Ref{public:    static MyCsvUtil * getInstance();    virtual bool init();    //加载配置文件    voID loadfile(const char * sPath);    //获取某行某列的值    cocos2d::Value getValue(int iRow,int iCol,const char * csvfilePath);    //获取值并转化为字符串    const std::string getStr(int iRow,const char * csvfilePath);    //获取值并转换为整形    const int getInt(int iRow,const char * csvfilePath);    //获取文件的行和列的数量    const cocos2d::Size getfileSize(const char * csvfilePath);private:    static MyCsvUtil * ms_CsvUtil;    cocos2d::Map<std::string,CsvData *> m_CsvMap;};#endif//函数实现文件#include "MyCsvUtil.h"#include "StringUtil.h"USING_NS_CC;MyCsvUtil * MyCsvUtil::ms_CsvUtil = nullptr;MyCsvUtil * MyCsvUtil::getInstance(){    if (ms_CsvUtil == nullptr)    {        ms_CsvUtil = new MyCsvUtil();        if (ms_CsvUtil && ms_CsvUtil->init() )        {            ms_CsvUtil->autorelease();            ms_CsvUtil->retain();        }        else        {            CC_SAFE_DELETE(ms_CsvUtil);            ms_CsvUtil = nullptr;        }    }    return ms_CsvUtil;}bool MyCsvUtil::init(){    if (!TBack::init())    {        return false;    }    return true;}//加载文件voID MyCsvUtil::loadfile(const char * sPath){    //存放一个csv文件的对象    CsvData * csvData = CsvData::create();    //读取路径所在文件的数据,保存到列表中    std::string str = fileUtils::getInstance()->getStringFromfile(sPath);    //将得到的数据按换行符分开,放到列表中    ValueVector linesList = StringUtil::getInstance()->split(str.c_str(),"\n");    //把每一行的字符拆分开来(按都好分隔)    for (auto value : linesList)    {        //将一行的字符串按逗号分隔,然后存放到列表中,最后将列表存放到CsvData对象里        //换句话说,csvData将成为一个二维表格,记录了配置文件行和列的字符串        ValueVector tArr = StringUtil::getInstance()->split(value.asstring().c_str(),",");        csvData->addlineData(tArr);    }    //将CsvData对象添加到字典里    m_CsvMap.insert(sPath,csvData);}//获取文件规格const Size MyCsvUtil::getfileSize(const char * csvfilePath){    //取出配置文件的二维表格    auto csvData = m_CsvMap.at(csvfilePath);    //如果配置文件不存在,则加载配置文件    if (csvData == nullptr)    {        loadfile(csvfilePath);        csvData = m_CsvMap.at(csvfilePath);    }    //调用了csvData类的函数    Size size = csvData->getRowColNum();    return size;}//获取文件某行某列Value MyCsvUtil::getValue(int iRow,const char * csvfilePath){    auto csvData = m_CsvMap.at(csvfilePath);    if (csvData == nullptr)    {        loadfile(csvfilePath);        csvData = m_CsvMap.at(csvfilePath);    }    //获取第iRow行数据    ValueVector rowVector = csvData->getSinglelineData(iRow);    //获取第iCol列数据    Value colValue = rowVector.at(iCol);    return colValue;}//获取文件某行某列并转换为字符串const std::string MyCsvUtil::getStr(int iRow,const char * csvfilePath){    Value val = Value();    val = getValue(iCol,iCol,csvfilePath);    return val.asstring();}//获取文件某行某列并转换为整型const int MyCsvUtil::getInt(int iRow,const char * csvfilePath){    Value val = Value();    val = getValue(iRow,csvfilePath);    return val.asInt();}

最后,我们就可以在其他的程序里面包含这个Csv文件读取工具类的头文件,就可以使用它了。
这是我在调试模式下测试的结果:

#include "MyCsvUtil.h"/*------测试代码段-------*/const char * sPath = "monster.csv";//文件路径MyCsvUtil::getInstance()->loadfile(sPath);//加载文件//获得第1行第1列数据Value firstMonstername = MyCsvUtil::getInstance()->getValue(1,1,sPath);//获得第2行第1列数据Value secMonstername = MyCsvUtil::getInstance()->getValue(2,sPath);   //打印结果log("%s",firstMonstername.asstring().c_str());log("%s",secMonstername.asstring().c_str());

输出结果:

总结

以上是内存溢出为你收集整理的cocos2d-x学习笔记——Csv文件读取工具全部内容,希望文章能够帮你解决cocos2d-x学习笔记——Csv文件读取工具所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/1061635.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-25
下一篇 2022-05-25

发表评论

登录后才能评论

评论列表(0条)

保存