在我们的游戏中,经常需要将策划的数值配置成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()
{ } 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 = ;
pBuffer = CCFileUtils::sharedFileUtils()->getFileData(pathKey.c_str(), "r", &bufferSize); std::string tmpStr = (char*)pBuffer;
std::string fileContent = tmpStr.substr(, bufferSize); std::vector<std::string> line;
rowSplit(line, fileContent, '\n');
for (unsigned int i = ; 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, );
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() - ] == '\r') {
line = line.substr(, line.length() - );
} std::string field;
unsigned int i = , j = ;
while (j < line.length()) {
if (line[i] == '"') {
//有引号
j = getFieldWithQuoted(line, field, i);
} else {
j = getFieldNoQuoted(line, field, i);
} fields.push_back(field);
i = j + ; //解析下一个field, +1为了跳过当前的分隔符
}
} int GCCsvHelper::getFieldWithQuoted(const std::string &line, std::string &field, int i)
{
unsigned int j = ;
field = std::string();
if (line[i] != '"') {
//不是引号起始,有问题
CCLOGERROR("start char is not quote when call %s", __FUNCTION__);
return -;
} for (j = i + ; j < line.length() - ; ++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 = ;
//找到下一个分隔符位置
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 = ; i < csv->getRowLength(); ++i) {
for (int j = ; j < csv->getColLength(); ++j) {
line += csv->getData(i, j);
line += ";";
} CCLabelTTF *pLbl = CCLabelTTF::create(line.c_str(), "Arial", );
pLbl->setColor(ccc3(, , ));
pLbl->setPosition(ccp(visibleSize.width / , visibleSize.height - - i * ));
addChild(pLbl); line = "";
} delete csv;
}

测试结果:

[cocos2dx utils] cocos2dx读取,解析csv文件的更多相关文章

  1. 如何用Java解析CSV文件

    首先看一下csv文件的规则: csv(Comma Separate Values)文件即逗号分隔符文件,它是一种文本文件,可以直接以文本打开,以逗号分隔.windows默认用excel打开.它的格式包 ...

  2. .NET 上传并解析CSV文件存库

    1.前端: 放置浏览按钮 <div class="row inner_table text-center"> <input id="fileId&quo ...

  3. java opencsv解析csv文件

    记一次使用opencsv解析csv文件时碰到的坑 最近在开发过程中需要解析csv文件,公司用的解析工具是opencsv,在根据opencsv的官方文档去解析时发现csv文件中含有繁体字,使用其自带的C ...

  4. C语言读取写入CSV文件 [一]基础篇

    本系列文章目录 [一] 基础篇 [二] 进阶篇--写入CSV [三] 进阶篇--读取CSV 什么是CSV? CSV 是一种以纯文本形式存储的表格数据,具体介绍如下(来自维基百科): 逗号分隔值(Com ...

  5. php解析.csv文件

    public function actionImport() { //post请求过来的 $fileName = $_FILES['file']['name']; $fileTmpName = $_F ...

  6. boost::property_tree读取解析.xml文件

    boost::property_tree读取解析.xml文件 1)read_xml 支持中文路径  boost::property_tree::wptree wpt;    std::locale:: ...

  7. boost::property_tree读取解析ini文件--推荐

    boost::property_tree读取解析ini文件 #include "stdafx.h" #include <iostream> #include <b ...

  8. 读取gzmt.csv文件,计算均值及概率

    问题: 读取gzmt.csv文件所有数据,选取收盘价格(倒数第二列),计算20天均值,权重取成交量(选做:时间权重为半衰期为15天):将该均值修剪为超过600的都设置为1000,并打印出该均值超过55 ...

  9. jmeter读取本地CSV文件

    用jmeter录制考试上传成绩等脚本时,出现的问题及解决方法如下: 1.beanshell前置处理器,不能读取本地csv文件里的数据: 方法一: 在beanshell里不能直接从本地的csv文件里读取 ...

随机推荐

  1. codeforces 600A Extract Numbers

    模拟题,意思是一个字符串,单词直接用','或';'来分割,可以为空,把不含前导0的整数和其他单词分别放入A和B.按照一定格式输出. 没有用stl的习惯.维护两个下标i,j,表示开区间(i,j),两段补 ...

  2. 破解 D-H 协议

    756: 破解 D-H 协议 时间限制: 1 Sec  内存限制: 128 MB提交: 78  解决: 18[提交] [状态] [讨论版] [命题人:admin] 题目描述 Diffie-Hellma ...

  3. AngularJs学习笔记-服务

    服务 (1)在模块中声明的服务对所有组件可见 (2)在组件中声明的服务对自己本身和其子组件 (3)在组件中声明的服务会覆盖在模块中声明的服务 (4)通过@Injectable()装饰器可以在服务中注入 ...

  4. github不能加载css、js解决办法

    很奇怪,上午在公司还能正常访问github,晚点访问却有问题,页面样式明显错乱. 在FireFox下用F12开发者工具一看,有2条css和2条js 404 了,猜想应该是github的DNS被GFW污 ...

  5. 自建ssr(谷歌云免费试用一年)

    近期我一个朋友的VPN到期了,他也不想再去续费,同时发现谷歌云第一年申请时是免费的,所以他就自己搭建了一个自己专属的VPN 以下是他的搭建教程:  本教程难点在于申请免费试用资格 谷歌云+ssr搭建免 ...

  6. react的constructor和super的具体含义和使用

    1.constructor( )-----super( )的基本含义 这是ES6对类的默认方法,通过 new 命令生成对象实例时自动调用该方法.并且,该方法是类中必须有的,如果没有显示定义,则会默认添 ...

  7. nginx限制ip访问某些特定url

    这两天百度云给我发了一些安全报警邮件,其中一条是有些陌生ip频繁尝试登录我的后台账户,也就是www.runstone.top/admin.给出的建议是限制这些ip访问/admin/这个url,于是经过 ...

  8. Docker容器学习--1

    Docker是PaaS 提供商 dotCloud 开源的一个基于 LXC 的高级容器引擎,源代码托管在 Github 上, 基于go语言并遵从Apache2.0协议开源.Docker是通过内核虚拟化技 ...

  9. windows_Bat_Scripts查看系统IP-更改regedit-更新系统补丁

    1.1    脚本名称 Update_patch.bat 1.2    脚本代码 @echo off :menu cls mode con cols=48 lines=27 & color 0 ...

  10. 与SVN相关的程序的调试问题【转】

    解决eclipse中出现Resource is out of sync with the file system问题. 分析:有时候因为时间紧迫的原因,所以就没去管它,今天再次遇到它,实在看着不爽,所 ...