1.为什么是CSV?
a,同样的数据放到CSV中要比放在xml和json中要小。
b,CSV的解析也比较简单。
c.策划编辑方便,策划比较擅长使用excel,使用CSV能够使用excel直接导出,不用再解析为其他格式。
2.解析思路:
用类似NotePad++类的软件打开CSV,会发现CSV的数据其实是一行一行的,每一行就代表了一条数据。那么,我们就需要将CSV数据文件
解析为一行一行的就好了。
3.一个小Demo
TestCSV.h
#ifndef _TSXT_CSV_H_ #define _TSXT_CSV_H_ #include "cocos2d.h" #include "../self/SF.h" class TestCSV : public cocos2d:: Ref { public : static const char * FILE_NAME ; static cocos2d :: Vector< TestCSV *> s_textCSVVec ; static bool initStatic(); static void finalizeStatic(); public : TestCSV (); ~ TestCSV(); virtual bool init( std :: map< std :: string,std:: string > row ); private : CC_SYNTHESIZE_READONLY (int,m_idx,Index); CC_SYNTHESIZE_READONLY ( std:: string,m_name,Name ); CC_SYNTHESIZE_READONLY ( std:: string,m_value,Value ); }; #endif
TestCSV.cpp
#include "TestCSV.h" USING_NS_CC ; const char * TestCSV :: FILE_NAME = "test_csv.csv" ; cocos2d :: Vector< TestCSV *> TestCSV ::s_textCSVVec ; bool TestCSV :: initStatic() { std :: string data = SFUtils:: getFileData (FILE_NAME ); IF_NULL_RETURN_FALSE (data . c_str()); /*CSV格式的文件每一行最后都是\n\r,所以,可以根据其来将每一行分开*/ std :: vector< std :: string> strVec = SFUtils :: splitString( data,"\r" ); /*dataVec用来存储所有行的信息,每个信息都是成对儿出现的map<key:string,value:string> 这里的key即ID,name等 */ std :: vector< std :: map< std :: string,std:: string > > dataVec ; /*解析第一行,第一行的数据将是后面行的key值*/ std :: vector< std :: string> nameVec = SFUtils ::splitString ( strVec[ 0 ],"," ); /*解析所有的行,并且添加的dataVec中*/ for ( int i = 1 ; i < strVec. size (); i ++) { std :: map< std :: string,std:: string > rowMap ; std :: vector< std :: string> valueVec = SFUtils ::splitString ( strVec[ i ]," ); for ( int j = 0 ; j < valueVec. size (); j ++) { rowMap . insert( std :: make_pair( nameVec [j ],valueVec [j ])); } dataVec . push_back( rowMap ); } /*确保数组中没有数据*/ s_textCSVVec .clear (); /*将数据转换为数据对象*/ for ( int i = 0 ; i < dataVec. size () - 1 ; i ++) { TestCSV * pData = new ( std:: nothrow )TestCSV (); if ( pData &&pData -> init( dataVec . at( i ))) { s_textCSVVec .pushBack ( pData); } else { CC_SAFE_RELEASE (pData ); } } return true ; } void TestCSV :: finalizeStatic() { s_textCSVVec .clear (); } TestCSV :: TestCSV() : m_idx(- 1 ) {} TestCSV :: ~TestCSV () {} bool TestCSV :: init( std :: map< std :: string,std:: string > row ) { /*解析数据*/ m_idx = atoi( row ["ID" ]. c_str()); m_name = row[ "name" ]; m_value = row[ "value" ]; return true ; }
用到的其他方法:
std :: string SFUtils ::getFileData ( const char * pFileName) { std :: string filePath = FileUtils :: getInstance()-> fullPathForFilename (pFileName ); FileUtils ::getInstance ()-> setPopupNotify( false ); ssize_t fileSize = 0 ; std :: string data = FileUtils :: getInstance()-> getStringFromFile (filePath . c_str()); FileUtils ::getInstance ()-> setPopupNotify( true ); return data ; } //字符串拆分 std :: vector< std :: string> SFUtils:: splitString ( std:: string str,std :: string pattern ) { std :: string:: size_type pos ; std :: vector< std :: string> result; str += pattern; unsigned int size = str . size(); for ( unsigned int i = 0 ; i < size ; i ++) { pos = str. find (pattern,i ); if ( pos < size) { std :: string s = str. substr (i,pos - i ); result .push_back ( s); i = pos + pattern . size() - 1 ; } } return result ; }用到的数据: