现在的位置: 首页 > 综合 > 正文

在Mac系统下Excel转csv文件中文乱码问题解决

2013年08月27日 ⁄ 综合 ⁄ 共 3150字 ⁄ 字号 评论关闭

导出方式

问题的原因是编码方式不同造成的,解决问题需要借助一个工具

Numbers,

下载地址: http://soft.macx.cn/5144.htm

安装完成后用Numbers打开Excel文档;

在最上方点击:共享->导出

出现

在这里选择csv,编码格式一定要选择UTF-8,然后点击下一步导出;

解析方式

在Mac下导出的csv是以逗号分割的;

下面是封装的解析类

CSVParse.h

#include <stdio.h>
#include <vector>

using namespace std;

class CSVParse {
    
public:
    int row;
    int col;
    
public:
    //调用解析
    CSVParse(const char* fileName, string sep = ",");
    ~CSVParse();
    
private:
    /**
     *  分隔符
     */
    string m_fieldsep;
    
    /**
     *  容器,存储从CSV里读取出来的数据
     */
    vector<vector<string> > m_data;
    
private:
    void split(vector<string>& field,string line);
    int advplain(const string& line, string& fld, int);
    int advquoted(const string& line, string& fld, int);
    
    /**
     *  删除替换特定字符
     */
    void deleteChar(std::string* str);
    
public:
    /**
     *  打开文件
     */
    bool openFile(const char* fileName);
    
    /**
     *  取数据
     */
    const char* getData(int m,int n);
};

CSVParse.cpp

#include "cocos2d.h"
#include "CSVParse.h"

CSVParse::CSVParse(const char* fileName, string sep)
:m_fieldsep(sep)
{
    openFile(fileName);
}

CSVParse::~CSVParse()
{
    for (int i=0; i<m_data.size(); i++) {
        m_data[i].clear();
    }
    m_data.clear();
}

void CSVParse::split(vector<string>& field,string line)
{
    string fld;
    int i, j;
    
    if (line.length() == 0)
        return ;
    i = 0;
    
    do {
        if (i < line.length() && line[i] == '"')
            j = advquoted(line, fld, ++i);
        else
            j = advplain(line, fld, i);
        
        field.push_back(fld);
        i = j + 1;
    } while (j < line.length());
    
}

int CSVParse::advquoted(const string& s, string& fld, int i)
{
    int j;
    
    fld = "";
    for (j = i; j < s.length(); j++)
    {
        if (s[j] == '"' && s[++j] != '"')
        {
            int k = s.find_first_of(m_fieldsep, j);
            if (k > s.length())
                k = s.length();
            for (k -= j; k-- > 0; )
                fld += s[j++];
            break;
        }
        fld += s[j];
    }
    return j;
}

int CSVParse::advplain(const string& s, string& fld, int i)
{
    int j;
    
    j = s.find_first_of(m_fieldsep, i);
    if (j > s.length()) 
        j = s.length();
    fld = string(s, i, j-i);
    return j;
}


const char* CSVParse::getData(int m,int n)
{
    if ( m<0 || m>=m_data.size() || n<0 || n>=m_data[m].size() ) {
        return "";
    }
    
    //printf("%d,%d,%s\n", m, n, m_data[m][n].c_str());
    
    return m_data[m][n].c_str();
}

bool CSVParse::openFile(const char* fileName)
{
    //获取全路径
    string pathKey = cocos2d::CCFileUtils::sharedFileUtils()->fullPathFromRelativePath(fileName);
    
    //打开文件
    //    size_t size = 0;
    FILE *fp = fopen(pathKey.c_str(), "r");
    if( !fp ) {
        CCLOG("打开文件%s失败", pathKey.c_str());
        return false;
    }
    
    //获取文件字节数
    //    fseek(fp, 0, SEEK_END);
    //    size = ftell(fp);
    //    fseek(fp, 0, SEEK_SET);
    
    //读取内容
    //    unsigned char* out = (unsigned char*)malloc(size);
    //    size_t read = fread(out, 1, size, fp);
    //    if( read != size ) {
    //        CCLOG("读取文件%s失败", pathKey.c_str());
    //        free(out);
    //        *out = NULL;
    //        return false;
    //    }
    
    char tmpChar[2048] = {0};
    string s;
    
    //去掉\r
    int lineIndex = 0;
    
    //读取第一行
    fgets(tmpChar, 2048, fp);
    while( strlen(tmpChar) > 0 )
    {
        s = tmpChar;
        //printf("%d = %s", lineIndex, tmpChar);
        
        //删除和替换掉多余字符
        deleteChar(&s);
        
        //拆分掉文本
        std::vector<string> field;
        split(field, s);
        
        //第一行和第一列是无用数据,所以不存.
        if(lineIndex > 0){
            field.erase(field.begin());
            m_data.push_back(field);
        }
        lineIndex++;
        
        //读取下一行
        tmpChar[0] = '\0';
        fgets(tmpChar, 2048, fp);
    }
    
    row = m_data.size();
    col = m_data[0].size();
    
    //测试,输出内容
//    for (int i=0; i<m_data.size(); i++) {
//        for (int k=0; k<m_data[i].size(); k++) {
//            CCLOG("--------->%s",getData(i, k));
//        }
//    }
    
    fclose(fp);
    
    return true;
}


void CSVParse::deleteChar(std::string* str){
    string::iterator it;
    int index = 0;
    for (; index < str->size(); )
    {
        it = str->begin()+index;
        if ( *it == '\r' || *it == '\n' )
        {
            str->erase(it);
        } 
        else{
            index++;
        }
    }    
}

解析类的用法

langFile为要解析的文件名

    CSVParse* csv = newCSVParse(langFile);

得到CSVParse对象后可以调用

const char* getData(int m,int n);

传入行和列可以得到想要的数据

代码下载:

http://download.csdn.net/detail/dingkun520wy/5263136

抱歉!评论已关闭.