#include "CSVParser.h"
namespace CSVParser {
Csv::Csv(const string& filename) {
Parse(filename);
}
Csv::~Csv() {
}
void Csv::Load(const string& filename, string& Data)
{
ssize_t len = 0;
unsigned char *data = NULL;
auto strPath = FileUtils::getInstance()->fullPathForFilename(filename);
data = FileUtils::getInstance()->getFileData(strPath.c_str(),"r", &len);
Data.assign((char *)data, len);
free(data);
}
void Csv::Parse(const string& filename)
{
// 清除之前的数据
m_content.clear();
m_strErrorInfo.clear();
string text;
Load(filename, text);
if (text.size() == 0) {
return;
}
// 定义状态
enum StateType {
NewFieldStart, // 新字段开始
NonQuotesField, // 非引号字段
QuotesField, // 引号字段
FieldSeparator, // 字段分隔
QuoteInQuotesField, // 引号字段中的引号
RowSeparator, // 行分隔符字符1,回车
Error, // 语法错误
};
Row Fields = Row();
string strField;
// 设置初始状态
StateType State = NewFieldStart;
for (int i = 0, size = text.size(); i < size; ++i) {
const char& ch = text[i];
switch (State) {
case NewFieldStart: { // 新字段开始
if (ch == '"') {
State = QuotesField;
}
else if (ch == ',') {
Fields.push_back("");
State = FieldSeparator;
}
else if (ch == '\r' || ch == '\n') {
m_strErrorInfo = "语法错误:有空行";
State = Error;
}
else {
strField.push_back(ch);
State = NonQuotesField;
}
}
break;
case NonQuotesField: { // 非引号字段
if (ch == ',') {
Fields.push_back(strField);
strField.clear();
State = FieldSeparator;
}
else if (ch == '\r') {
Fields.push_back(strField);
State = RowSeparator;
}
else {
strField.push_back(ch);
}
}
break;
case QuotesField: { // 引号字段
if (ch == '"') {
State = QuoteInQuotesField;
}
else {
strField.push_back(ch);
}
}
break;
case FieldSeparator: { // 字段分隔
if (ch == ',') {
Fields.push_back("");
}
else if (ch == '"') {
strField.clear();
State = QuotesField;
}
else if (ch == '\r') {
Fields.push_back("");
State = RowSeparator;
}
else {
strField.push_back(ch);
State = NonQuotesField;
}
}
break;
case QuoteInQuotesField: { // 引号字段中的引号
if (ch == ',') {
// 引号字段闭合
Fields.push_back(strField);
strField.clear();
State = FieldSeparator;
}
else if (ch == '\r') {
// 引号字段闭合
Fields.push_back(strField);
State = RowSeparator;
}
else if (ch == '"') {
// 转义
strField.push_back(ch);
State = QuotesField;
}
else {
m_strErrorInfo = "语法错误: 转义字符 \" 不能完成转义 或 引号字段结尾引号没有紧贴字段分隔符";
State = Error;
}
}
break;
case RowSeparator: { // 行分隔符字符1,回车
if (ch == '\n') {
m_content.push_back(Fields);
Fields = Row(); // Fields.clear();
strField.clear();
State = NewFieldStart;
}
else {
m_strErrorInfo = "语法错误: 行分隔用了回车 \\r。但未使用回车换行 \\r\\n ";
State = Error;
}
}
break;
case Error: { // 语法错误
return;
}
break;
default: break;
}
}
// end for
switch (State) {
case NewFieldStart: {
// Excel导出的CSV每行都以/r/n结尾。包括最后一行
}
break;
case NonQuotesField: {
Fields.push_back(strField);
m_content.push_back(Fields);
}
break;
case QuotesField: {
m_strErrorInfo = "语法错误: 引号字段未闭合";
}
break;
case FieldSeparator: {
Fields.push_back("");
m_content.push_back(Fields);
}
break;
case QuoteInQuotesField: {
Fields.push_back(strField);
m_content.push_back(Fields);
}
break;
case RowSeparator: {
}
break;
case Error: {
}
break;
default: break;
}
setHeader();
}
void Csv::setHeader()
{
m_header.clear();
for (unsigned int i = 0; i < m_content[0].size(); i++) {
m_header.push_back(m_content[0][i]);
}
for (unsigned int i = 0; i < m_content.size(); i++) {
m_content[i].setHeader(&m_header);
}
}
Row& Csv::operator[](unsigned int key)
{
if (key < m_content.size()) return m_content[key];
throw "can't return this row (doesn't exist)";
}
}
CSV.rar_cocos2dx_csv
版权申诉
24 浏览量
2022-09-24
07:56:40
上传
评论
收藏 2KB RAR 举报
alvarocfc
- 粉丝: 105
- 资源: 1万+
最新资源
- Keil.STM32L0xx-DFP.2.2.0
- 基于安霸A7LA30行车记录仪方案开发评估板硬件CADENCE设计(原理图+PCB6层板)文件.zip
- shu.c
- 批量Word文件转PDF
- 基于STM32F103单片机+LD3320A+HLK-RM04 智能家居控制板Altium硬件(原理图+PCB)文件.zip
- yolo行人跌倒检测数据集(1440张图片,txt格式标注文件)
- yolo垃圾分类数据集(2743张图片,txt格式的标注文件)
- 暴风5播放器,老暴风播放器,暴风播放器5
- win11恢复传统桌面右键菜单
- (自适应手机端)居家用品纸盘纸盒纸杯卫生纸巾生产网站pbootcms模板 生活日用品生产厂家网站源码下载.zip
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈