[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, ‘\n‘);
    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] == ‘\r‘) {
        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;
}

测试结果:

时间: 2024-10-19 20:48:05

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

练习:读取解析CSV文件,将读取结果输出的控制台上,并封装到4个Teacher对象中.

/** *    读取解析CSV文件,将读取结果输出的控制台上,并封装到4个Teacher对象中. *    1, 土鳖, 13101015338, 北京海淀区 2, 咪咪, 13201015338, 北京朝阳区 3, 小仓, 13601015818, 北京宣武区 4, 饭岛爱, 13201025818, 北京朝阳区 /** * 读取解析CSV文件,将读取结果输出的控制台上,并封装到4个Teacher对象中. * 1, 土鳖, 13101015338, 北京海淀区 2, 咪咪, 13201015

如何用Java解析CSV文件

首先看一下csv文件的规则: csv(Comma Separate Values)文件即逗号分隔符文件,它是一种文本文件,可以直接以文本打开,以逗号分隔.windows默认用excel打开.它的格式包括以下几点(它的格式最好就看excel是如何解析的.): ①每条记录占一行: ②以逗号为分隔符: ③逗号前后的空格会被忽略: ④字段中包含有逗号,该字段必须用双引号括起来: ⑤字段中包含有换行符,该字段必须用双引号括起来: ⑥字段前后包含有空格,该字段必须用双引号括起来: ⑦字段中的双引号用两个双引

C++ 中使用boost::property_tree读取解析ini文件

boost 官网 http://www.boost.org/ 下载页面 http://sourceforge.net/projects/boost/files/boost/1.53.0/ 我下载的是 boost_1_53_0.tar.gz 使用系统  ubuntu 12.10 一.解压 [plain] view plaincopy tar -zxvf  boost_1_53_0.tar.gz 得到一个文件夹 boost_1_53_0,  拷贝其子目录 boost 到以下路径 [plain] vi

Qt解析CSV文件

最近需要解析Excel文件,于是顺带写了解析CSV的代码 定义数据类型LX::Sheet 1 #ifndef LX_H 2 #define LX_H 3 4 #include <QString> 5 #include <QStringList> 6 7 namespace LX 8 { 9 class Sheet 10 { 11 enum FieldType{STRING, INT, DOUBLE, BOOL}; 12 public: 13 Sheet(){} 14 Sheet(S

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

boost::property_tree读取解析ini文件 [cpp] view plaincopy #include "stdafx.h" #include <iostream> #include <boost/property_tree/ptree.hpp> #include <boost/property_tree/ini_parser.hpp> int main() { boost::property_tree::ptree pt; boos

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

1)read_xml 支持中文路径  boost::property_tree::wptree wpt;    std::locale::global(std::locale(""));    boost::property_tree::xml_parser::read_xml("E:\\测试\\test.xml",wpt); 2)get  ptree pt;    read_xml("D://test1.xml",pt); //读入一个xml文

php解析.csv文件

public function actionImport() { //post请求过来的 $fileName = $_FILES['file']['name']; $fileTmpName = $_FILES['file']['tmp_name']; //判断是否选择了上传的文件 if (empty($fileName)) { $data['message'] = "请选择要上传的文件"; return $this->render("batch_add", $

php解析csv文件

public function actionImport() { //post请求过来的 $fileName = $_FILES['file']['name']; $fileTmpName = $_FILES['file']['tmp_name']; //判断是否选择了上传的文件 if (empty($fileName)) { $data['message'] = "请选择要上传的文件"; return $this->render("batch_add", $

解析 csv文件 java &gt;&gt;&gt;&gt;&gt;最爱那水货

1 /** 2 * csv文件解析 <br> 3 * wx 微信明细数据 第1行是标题 ,最后2行 是总结 提取数据需要过滤<br> 4 * zfb 支付宝明细数据 前4行 和最后4行是总结 第5行是 标题 提取数据时需要过滤 5 * @param localPath 本地文件绝对路径 6 * @param flag 支付机构 wx zfb pos 7 * @return 8 */ 9 public List<String[]> csvAnalysis(String l