本文主要是用C++简单的实现了cocos2dx中对CSV文件的解析,由于能力有限,写的不好的地方提出来共同学习共同进步,
这里参考了笨木头使用LUA解析CSV文件点击打开链接还参考了另一位仁兄的C++代码,网址找不到了,真是抱歉
首先需要补充一点概念:什么是CSV文件??
就是一行为一条记录,每条记录以","作为分隔符啦划分字段(哈,详细内容请自行百度~~~)
ID,NAME,SEX,YEAR,REMARKET
1,张三,男,34,好好学习,天天向上
2,李四,女,25,你是谁啊你是谁
对CSV文件的解析,说简单一点就是对字符串的分割,下面说说我的字符串分割函数split
//字符串分割函数
void split(const std::string &str, const char *reps, std::vector<std::string> &tarVector)
{
std::string tarString(str);
while (!tarString.empty()) {
int pos = tarString.find_first_of(reps);
if (pos == std::string::npos) {
tarVector.push_back(tarString);
tarString.clear();
}
else {
tarVector.push_back(tarString.substr(0, pos));
tarString.erase(0, pos + strlen(reps));
}
}
}
代码还是比较好理解的,大体思路就是从字符串首开始搜索到分隔符(子串),然后提取出来,并删除子串和分隔符,直至结束
下面看头文件:
#ifndef __CSV_PARSER_H__
#define __CSV_PARSER_H__
#include "cocos2d.h"
class LineString
{
public:
LineString(const std::string &str);
virtual ~LineString();
size_t getColumnCount() const { return _lineStr.size(); }
std::string &operator[](size_t index)
{
CCASSERT(index < this->getColumnCount(), "invalid index in lineInfo");
return _lineStr[index];
}
protected:
void initWithString(const std::string &str);
private:
std::vector<std::string> _lineStr;
};
class CsvParser
{
public:
CsvParser();
virtual ~CsvParser();
void parseWithFile(const std::string &csvFilename);
size_t getRowCount() const { return _dataInfo.size(); }
size_t getColumnCount() const { return _titles.size(); }
LineString &operator[](size_t index)
{
CCASSERT(index < this->getColumnCount(), "invalid index in lineInfo");
return _dataInfo[index];
}
private:
std::vector<std::string> _titles;
std::vector<LineString> _dataInfo;
};
#endif // __CSV_PARSER_H__
头文件中定义了两个类,一个是用于行信息管理的LineStrng类,并重载了[]运算符,另一个才是真正的解析CSV文件的类CsvParser,函数都比较简单
下面看具体的实现:
#include "CsvParser.h"
USING_NS_CC;
//字符串分割函数
void split(const std::string &str, const char *reps, std::vector<std::string> &tarVector)
{
std::string tarString(str);
while (!tarString.empty()) {
int pos = tarString.find_first_of(reps);
if (pos == std::string::npos) {
tarVector.push_back(tarString);
tarString.clear();
}
else {
tarVector.push_back(tarString.substr(0, pos));
tarString.erase(0, pos + strlen(reps));
}
}
}
LineString::LineString(const std::string &str)
{
this->initWithString(str);
}
LineString::~LineString()
{
}
void LineString::initWithString(const std::string &str)
{
split(str, ",", _lineStr);
}
//
CsvParser::CsvParser()
{
}
CsvParser::~CsvParser()
{
}
void CsvParser::parseWithFile(const std::string &csvFilename)
{
std::string fullPth = FileUtils::getInstance()->fullPathForFilename(csvFilename);
std::string tokenStr = FileUtils::getInstance()->getStringFromFile(fullPth);
//获取行信息
std::vector<std::string> lineInfo;
split(tokenStr, "\n\r", lineInfo);
//得到标题
split(lineInfo[0], ",", _titles);
//获取具体内容
size_t rowCount = lineInfo.size();
for (int i = 1; i < rowCount; i++) {
LineString lineStr(lineInfo[i]);
_dataInfo.push_back(lineStr);
}
}
需要注意的是我的文件读取是直接使用的cocos中的FilUtils类的std::string tokenStr = FileUtils::getInstance()->getStringFromFile(fullPth);有兴趣的可以自己去扒一扒源代码,你也可以使用其他的方式去读取获得,正所谓条条大道通罗马~~~~
使用起来也就很简单了:
CsvParser csv;
csv.parseWithFile("csvTest.csv");
for (int i = 0; i < csv.getRowCount(); i++) {
for (int j = 0; j < csv.getColumnCount(); j++) {
log("%s", csv[i][j].c_str());
}
}
看看打印出来什么。。。。
第一次写blog,好紧张,隔壁的回来了,有点吵吵的,这篇文章就到这里吧,有点犯困了。。。。