csv文件读取类的实现

     CSV(Comma-Separated Values,逗号分隔的值)是一种简单、实用的文件格式,用于存储和表示包括文本、数值等各种类型的数据。CSV 文件通常以 .csv 作为文件扩展名。这种文件格式的一个显著特点是:文件内的数据以逗号( ,)或空格 分隔,呈现一个表格形式。CSV 文件已广泛应用于存储、传输和编辑数据。

      CSV 文件基于纯文本格式,因此可以使用任何文本编辑器(如Notepad)轻松打开和编辑。它让程序开发人员喜欢的是既容易生成,还可以用其他编辑器编辑;作为数据输入时,也很好验证读取是否正确。本文介绍一个csv文件读取类,输入文件名就可以按行和列获取每个单元格的内容。

输入文件名,解析数据类:

#ifndef _CSV_FILE_
#define _CSV_FILE_

#include <fstream>
#include <vector>
#include <string>
#include <iostream>

using namespace std;

typedef vector< string > VecString;
typedef vector< VecString > MatrixString;

class CVSFile
{
public:
	CVSFile();

	//以文件名初始化表格数据
	bool Init(const char* szFileName, char cSpliteToken = ',');

	//以指定分隔符从一行数据中获取关键字列表
	bool Splite(const string& strLine, VecString& vecString);

private:
	// 检测读出的数据是否合法
	bool _CheckDataValid();

protected:
	MatrixString m_content;
	char m_cSpliteToken;
};

#endif
#include "CVSFile.h"


CVSFile::CVSFile()
{
	m_content.clear();
}

bool CVSFile::Init( const char* szFileName, char cSpliteToken)
{
	ifstream inFile(szFileName);

	if (!inFile)
	{
		return false;
	}

	//获取分隔符
	m_cSpliteToken = cSpliteToken;

	// 每次读取一行文本内容直至文件结尾
	string strLineContext;
	while (getline(inFile, strLineContext))
	{
		// 以指定分隔符获取每行信息列表
		VecString vecValue;
		Splite(strLineContext, vecValue);
		m_content.push_back(vecValue);
	}

	// 检验数据是否符合要求
	if (!_CheckDataValid())
	{
		return false;
	}
	
	return true;
}

bool CVSFile::Splite( const string& strLine, VecString& vecString )
{
	int nBegin = 0;
	int nEnd = 0;

	while ((nEnd = strLine.find_first_of(m_cSpliteToken, nBegin)) != string::npos)
	{
		vecString.push_back(strLine.substr(nBegin, nEnd - nBegin));
		nBegin = nEnd + 1;
	}

	if ((nBegin = strLine.find_last_of(m_cSpliteToken, strLine.length() - 1)) != string::npos)
	{
		vecString.push_back(strLine.substr(nBegin + 1, strLine.length() - 1));
	}
	
	return true;
}

bool CVSFile::_CheckDataValid()
{
	int nNumInOneLine = 0;

	MatrixString::const_iterator itRowData = m_content.begin();
	for (; itRowData != m_content.end(); itRowData++)
	{
		const VecString& curVecString = *itRowData;
		nNumInOneLine = curVecString.size();
		if (nNumInOneLine == 0)
		{
			return false;
		}		
	}

	return true;
}

      如果是普通的矩阵式csv文件读取,上面的类里,自己添加一个接口函数,从MatrixString里获取单元格的值就可以了。

       如果要读取的csv文件复杂一些,每个数据单独命名,有名称、数据类型和描述,如下:

namen11n12n13n14n15
typeint floatcharstringint
description
valuev11v12v13v14v15

单单上面的解析是不够的,需要对上面解析的数据进行二次加工。

#ifndef _GAME_CSV_FILE_
#define _GAME_CSV_FILE_

#include <vector>
#include <string>

#include "CVSFile.h"

using namespace std;

enum KEY_TYPE
{
	KEY_TYPE_NULL	= -1,		// 未知类型
	KEY_TYPE_EMPTY,			// 空类型
	KEY_TYPE_CHAR,			// 字符类型
	KEY_TYPE_DWORD,		// 整形类型
	KEY_TYPE_FLOAT,			// 浮点类型
	KEY_TYPE_STRING,		// 字符串类型
	KEY_TYPE_MAX				
};

// 字段类型名称表
static char* KeyTypeName[] = { "",
										"char",
										"dword",
										"float",
										"string"
										};

//字段类型信息结构
struct KEY
{
	string description;			//字段说明
	string name;					//字段名称
	KEY_TYPE eType;			//字段类型
};


const unsigned int DESCRIPTION_ROW_INDEX = 0;		//字段说明在csv表中的行号
const unsigned int NAME_ROW_INDEX = 1;					//字段名称在csv表中的行号
const unsigned int KEY_TYPE_ROW_INDEX = 2;			//字段类型在csv表中的行号
const unsigned int KEY_TYPE_ROW_NUM = KEY_TYPE_ROW_INDEX + 1;			//字段类型在csv表中的行数

class GameCSVFile : public CVSFile
{
public:
	GameCSVFile();

	// 通过文件名,获得字段类型信息
	bool Format(const char* szFileName);

private:
	// 通过字符串获得字段类型
	KEY_TYPE _GetKeyType(const string& strKeyType);

protected:
	vector< KEY > m_vecKeyType;	// 字段信息记录
};

#endif
#include "GameCSVFile.h"

GameCSVFile::GameCSVFile()
{
	m_vecKeyType.clear();
}

bool GameCSVFile::Format( const char* szFileName )
{
	if (!Init(szFileName))
	{
		return false;
	}

	// 字段定义行数不足,返回失败
	if (m_content.size() < KEY_TYPE_ROW_INDEX + 1)
	{
		return false;
	}

	// 形成字段说明数组
	for (unsigned int i = 0; i < m_content[DESCRIPTION_ROW_INDEX].size(); i++)
	{
		KEY curKey;

		curKey.description = m_content[DESCRIPTION_ROW_INDEX][i];
		curKey.name = m_content[NAME_ROW_INDEX][i];
		curKey.eType = _GetKeyType(m_content[KEY_TYPE_ROW_INDEX][i]);

		m_vecKeyType.push_back(curKey);
	}
	
	return true;
}

KEY_TYPE GameCSVFile::_GetKeyType( const string& strKeyType )
{
	for (int i = 0; i < sizeof(KeyTypeName); i++)
	{
		if (strKeyType.compare(KeyTypeName[i]) == 0)
		{
			return static_cast<KEY_TYPE>(i);
		}
	}
	
	return KEY_TYPE_NULL;
}

  另外还需要数据获取接口管理,这里不再贴出所有代码,有需要下载一下。

CSV文件读取类C++源代码

  • 9
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

previewer1024

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值