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

时间:2021-08-28 13:22:50

导出方式

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

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

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

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

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

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

在这里选择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