游戏开发过程中大家经常会使用到Csv文件保存数据,但是我们怎么把Csv文件的数据取出来呢,今天我要向大家介绍下解析Csv用的几个工具类
一.首先编写字符串工具类
1.h文件
#ifndef _StringUtil_H_
#define _StringUtil_H_
#include "cocos2d.h"
using namespace cocos2d;
using namespace std;
class StringUtil : public Ref
{
public:
virtual bool init();
static StringUtil * getInstance();
/* 用分隔符分割字符串,结果存放到一个列表中,列表中的对象为Value */
ValueVector split(const char * stcStr, const char * sSep);
private:
static StringUtil * m_StringUtil;
};
#endif
2..cpp文件
#include "StringUtil.h"
StringUtil * StringUtil::m_StringUtil = NULL;
StringUtil * StringUtil::getInstance()
{
if (m_StringUtil == NULL)
{
m_StringUtil = new StringUtil();
if (m_StringUtil && m_StringUtil->init())
{
m_StringUtil->autorelease();
m_StringUtil->retain();
}
else
{
CC_SAFE_DELETE(m_StringUtil);
m_StringUtil = NULL;
}
}
return m_StringUtil;
}
bool StringUtil::init()
{
return true;
}
cocos2d::ValueVector StringUtil::split(const char * stcStr, const char * sSep)
{
ValueVector stringList;
int size = strlen(stcStr);
//将数据转换为字符串对象
Value str = Value(stcStr);
int startIndex = 0;
int endIndex = 0;
endIndex = str.asString().find(sSep);
std::string lineStr;
//根据换行符拆分字符串,并添加到列表中
while (endIndex >0)
{
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;
}
二.Csv文件对象类
1..h文件
#ifndef _CsvData_H_
#define _CsvData_H_
#include "cocos2d.h"
using namespace cocos2d;
using namespace std;
class CsvData : public Ref
{
public:
virtual bool init();
CREATE_FUNC(CsvData);
void addLineData(ValueVector lineData); //添加一行数据
ValueVector getStringLineData(int iLine);//获取某行的数据
Size getRowColNum();//获取行列大小
private:
//存放Csv文件所有行的数据,试试这样理解:ValueVector<Value<ValueVecctor>>
ValueVector m_allLinesVec;
};
#endif
2..cpp文件
#include "CsvData.h"
void CsvData::addLineData(ValueVector lineData)
{
m_allLinesVec.push_back(Value(lineData));
}
bool CsvData::init()
{
return true;
}
cocos2d::ValueVector CsvData::getStringLineData(int iLine)
{
return m_allLinesVec.at(iLine).asValueVector();
}
cocos2d::Size CsvData::getRowColNum()
{
Size size = Size();
size.width = m_allLinesVec.size();
if (size.width > 0)
{
size.height = m_allLinesVec.at(0).asValueVector().size();
}
return size;
}
三.Csv文件读取工具类
1.h文件
#ifndef _CsvUtil_H_
#define _CsvUtil_H_
#include "cocos2d.h"
#include "CsvData.h"
using namespace cocos2d;
using namespace std;
class CsvUtil : public Ref
{
public:
virtual bool init();
static CsvUtil * getInstance();
void loadFile(const char * sPath);//加载配置文件
Value getValue(int iRow, int iCol, const char* csvFilePath);//获取某行某列的值
const std::string get(int iRow, int iCol, const char * csvFilePath);//获取值并转换为字符串
const int getInt(int iRow, int iCol, const char * csvFilePath);//获取值并转换为整型
const int getFloat(int iRow, int iCol, const char * csvFilePath);//获取值并转换为小数
const int getBool(int iRow, int iCol, const char * csvFilePath);//获取值并转换为布尔型
const Size getFileRowColNum(const char * csvFilePath);//获取文件的行和列数量
//根据某个列的值,查找该值所在的行
const int findValueInWithLine(const char * chValue, int iValueCol, const char * csvFilePath);
private:
static CsvUtil * m_CsvUtil;
Map<std::string, CsvData *>mCsvMap;//存放mCsvStrList-filePath的字典
};
#endif
2..cpp文件
#include "CsvUtil.h"
#include "StringUtil.h"
CsvUtil * CsvUtil::m_CsvUtil = NULL;
CsvUtil * CsvUtil::getInstance()
{
if (m_CsvUtil == NULL)
{
m_CsvUtil = new CsvUtil();
if (m_CsvUtil && m_CsvUtil->init())
{
m_CsvUtil->autorelease();
m_CsvUtil->retain();
}
else
{
CC_SAFE_DELETE(m_CsvUtil);
m_CsvUtil = NULL;
}
}
return m_CsvUtil;
}
bool CsvUtil::init()
{
return true;
}
void CsvUtil::loadFile(const char * sPath)
{
//存放一个Csv对象
CsvData * csvData = CsvData::create();
//读取数据,按行保存在列表中
std:: string str = FileUtils::getInstance()->getStringFromFile(sPath);
ValueVector lineList = StringUtil::getInstance()->split(str.c_str(), "\n");
//把每一行的字符串拆分出来(按逗号分隔)
for (auto value : lineList)
{
//将一行的字符串按逗号分隔,然后存放在列表,最后将列表存房贷CsvData对象里
//通俗理解,csvData将成为一个二维表格,记录了配置文件的行和列的字符串
ValueVector tArr = StringUtil::getInstance()->split(value.asString().c_str(), ",");
csvData->addLineData(tArr);
}
//添加列表到字典里
mCsvMap.insert(sPath, csvData);
}
const Size CsvUtil::getFileRowColNum(const char * csvFilePath)
{
//取出配置文件的二维表格
auto csvData = mCsvMap.at(csvFilePath);
//如果配置文件的数据不存在,则加载配置文件
if (csvData == nullptr)
{
loadFile(csvFilePath);
csvData = mCsvMap.at(csvFilePath);
}
Size size = csvData->getRowColNum();
return size;
}
cocos2d::Value CsvUtil::getValue(int iRow, int iCol, const char* csvFilePath)
{
auto csvData = mCsvMap.at(csvFilePath);
if (csvData == nullptr)
{
loadFile(csvFilePath);
csvData = mCsvMap.at(csvFilePath);
}
ValueVector rowVector = csvData->getStringLineData(iRow);//获取第iRow行的数据
Value colValue = rowVector.at(iCol);//获取iCol列数据
return colValue;
}
const std::string CsvUtil::get(int iRow, int iCol, const char * csvFilePath)
{
Value colValue = getValue(iRow, iCol, csvFilePath);
return colValue.asString();
}
const int CsvUtil::getInt(int iRow, int iCol, const char * csvFilePath)
{
Value colValue = getValue(iRow, iCol, csvFilePath);
return colValue.asInt();
}
const int CsvUtil::getFloat(int iRow, int iCol, const char * csvFilePath)
{
Value colValue = getValue(iRow, iCol, csvFilePath);
return colValue.asFloat();
}
const int CsvUtil::getBool(int iRow, int iCol, const char * csvFilePath)
{
Value colValue = getValue(iRow, iCol, csvFilePath);
return colValue.asBool();
}
四.获取示例代码,举例用HelloWroldSence.cpp文件中的init()函数添加代码
const char * sPath = "Monster.csv";//读取csv文件
CsvUtil::getInstance()->loadFile(sPath);
Value firstMonsterName = CsvUtil::getInstance()->getValue(2, 1, sPath);
Value secMonsterHp = CsvUtil::getInstance()->getValue(3, 3, sPath);
int aa = CsvUtil::getInstance()->getInt(3, 3, sPath);
log("firstMonsterName = %s ", firstMonsterName.asString().c_str());
log("secMonsterHp = %s", secMonsterHp.asString().c_str());
log("aa = %d", --aa);
看下打印的消息就能知道我们具体获取的哪些数据了
一.首先编写字符串工具类
1.h文件
#ifndef _StringUtil_H_
#define _StringUtil_H_
#include "cocos2d.h"
using namespace cocos2d;
using namespace std;
class StringUtil : public Ref
{
public:
virtual bool init();
static StringUtil * getInstance();
/* 用分隔符分割字符串,结果存放到一个列表中,列表中的对象为Value */
ValueVector split(const char * stcStr, const char * sSep);
private:
static StringUtil * m_StringUtil;
};
#endif
2..cpp文件
#include "StringUtil.h"
StringUtil * StringUtil::m_StringUtil = NULL;
StringUtil * StringUtil::getInstance()
{
if (m_StringUtil == NULL)
{
m_StringUtil = new StringUtil();
if (m_StringUtil && m_StringUtil->init())
{
m_StringUtil->autorelease();
m_StringUtil->retain();
}
else
{
CC_SAFE_DELETE(m_StringUtil);
m_StringUtil = NULL;
}
}
return m_StringUtil;
}
bool StringUtil::init()
{
return true;
}
cocos2d::ValueVector StringUtil::split(const char * stcStr, const char * sSep)
{
ValueVector stringList;
int size = strlen(stcStr);
//将数据转换为字符串对象
Value str = Value(stcStr);
int startIndex = 0;
int endIndex = 0;
endIndex = str.asString().find(sSep);
std::string lineStr;
//根据换行符拆分字符串,并添加到列表中
while (endIndex >0)
{
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;
}
二.Csv文件对象类
1..h文件
#ifndef _CsvData_H_
#define _CsvData_H_
#include "cocos2d.h"
using namespace cocos2d;
using namespace std;
class CsvData : public Ref
{
public:
virtual bool init();
CREATE_FUNC(CsvData);
void addLineData(ValueVector lineData); //添加一行数据
ValueVector getStringLineData(int iLine);//获取某行的数据
Size getRowColNum();//获取行列大小
private:
//存放Csv文件所有行的数据,试试这样理解:ValueVector<Value<ValueVecctor>>
ValueVector m_allLinesVec;
};
#endif
2..cpp文件
#include "CsvData.h"
void CsvData::addLineData(ValueVector lineData)
{
m_allLinesVec.push_back(Value(lineData));
}
bool CsvData::init()
{
return true;
}
cocos2d::ValueVector CsvData::getStringLineData(int iLine)
{
return m_allLinesVec.at(iLine).asValueVector();
}
cocos2d::Size CsvData::getRowColNum()
{
Size size = Size();
size.width = m_allLinesVec.size();
if (size.width > 0)
{
size.height = m_allLinesVec.at(0).asValueVector().size();
}
return size;
}
三.Csv文件读取工具类
1.h文件
#ifndef _CsvUtil_H_
#define _CsvUtil_H_
#include "cocos2d.h"
#include "CsvData.h"
using namespace cocos2d;
using namespace std;
class CsvUtil : public Ref
{
public:
virtual bool init();
static CsvUtil * getInstance();
void loadFile(const char * sPath);//加载配置文件
Value getValue(int iRow, int iCol, const char* csvFilePath);//获取某行某列的值
const std::string get(int iRow, int iCol, const char * csvFilePath);//获取值并转换为字符串
const int getInt(int iRow, int iCol, const char * csvFilePath);//获取值并转换为整型
const int getFloat(int iRow, int iCol, const char * csvFilePath);//获取值并转换为小数
const int getBool(int iRow, int iCol, const char * csvFilePath);//获取值并转换为布尔型
const Size getFileRowColNum(const char * csvFilePath);//获取文件的行和列数量
//根据某个列的值,查找该值所在的行
const int findValueInWithLine(const char * chValue, int iValueCol, const char * csvFilePath);
private:
static CsvUtil * m_CsvUtil;
Map<std::string, CsvData *>mCsvMap;//存放mCsvStrList-filePath的字典
};
#endif
2..cpp文件
#include "CsvUtil.h"
#include "StringUtil.h"
CsvUtil * CsvUtil::m_CsvUtil = NULL;
CsvUtil * CsvUtil::getInstance()
{
if (m_CsvUtil == NULL)
{
m_CsvUtil = new CsvUtil();
if (m_CsvUtil && m_CsvUtil->init())
{
m_CsvUtil->autorelease();
m_CsvUtil->retain();
}
else
{
CC_SAFE_DELETE(m_CsvUtil);
m_CsvUtil = NULL;
}
}
return m_CsvUtil;
}
bool CsvUtil::init()
{
return true;
}
void CsvUtil::loadFile(const char * sPath)
{
//存放一个Csv对象
CsvData * csvData = CsvData::create();
//读取数据,按行保存在列表中
std:: string str = FileUtils::getInstance()->getStringFromFile(sPath);
ValueVector lineList = StringUtil::getInstance()->split(str.c_str(), "\n");
//把每一行的字符串拆分出来(按逗号分隔)
for (auto value : lineList)
{
//将一行的字符串按逗号分隔,然后存放在列表,最后将列表存房贷CsvData对象里
//通俗理解,csvData将成为一个二维表格,记录了配置文件的行和列的字符串
ValueVector tArr = StringUtil::getInstance()->split(value.asString().c_str(), ",");
csvData->addLineData(tArr);
}
//添加列表到字典里
mCsvMap.insert(sPath, csvData);
}
const Size CsvUtil::getFileRowColNum(const char * csvFilePath)
{
//取出配置文件的二维表格
auto csvData = mCsvMap.at(csvFilePath);
//如果配置文件的数据不存在,则加载配置文件
if (csvData == nullptr)
{
loadFile(csvFilePath);
csvData = mCsvMap.at(csvFilePath);
}
Size size = csvData->getRowColNum();
return size;
}
cocos2d::Value CsvUtil::getValue(int iRow, int iCol, const char* csvFilePath)
{
auto csvData = mCsvMap.at(csvFilePath);
if (csvData == nullptr)
{
loadFile(csvFilePath);
csvData = mCsvMap.at(csvFilePath);
}
ValueVector rowVector = csvData->getStringLineData(iRow);//获取第iRow行的数据
Value colValue = rowVector.at(iCol);//获取iCol列数据
return colValue;
}
const std::string CsvUtil::get(int iRow, int iCol, const char * csvFilePath)
{
Value colValue = getValue(iRow, iCol, csvFilePath);
return colValue.asString();
}
const int CsvUtil::getInt(int iRow, int iCol, const char * csvFilePath)
{
Value colValue = getValue(iRow, iCol, csvFilePath);
return colValue.asInt();
}
const int CsvUtil::getFloat(int iRow, int iCol, const char * csvFilePath)
{
Value colValue = getValue(iRow, iCol, csvFilePath);
return colValue.asFloat();
}
const int CsvUtil::getBool(int iRow, int iCol, const char * csvFilePath)
{
Value colValue = getValue(iRow, iCol, csvFilePath);
return colValue.asBool();
}
四.获取示例代码,举例用HelloWroldSence.cpp文件中的init()函数添加代码
const char * sPath = "Monster.csv";//读取csv文件
CsvUtil::getInstance()->loadFile(sPath);
Value firstMonsterName = CsvUtil::getInstance()->getValue(2, 1, sPath);
Value secMonsterHp = CsvUtil::getInstance()->getValue(3, 3, sPath);
int aa = CsvUtil::getInstance()->getInt(3, 3, sPath);
log("firstMonsterName = %s ", firstMonsterName.asString().c_str());
log("secMonsterHp = %s", secMonsterHp.asString().c_str());
log("aa = %d", --aa);
看下打印的消息就能知道我们具体获取的哪些数据了