栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

C++读取读取csv、xls文件的类

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

C++读取读取csv、xls文件的类

由于经常要读取大量的数据进行分析,自己封装了一个C++的类,代替网上的rapidcsv库。一切以自己的需求为准,够用简略就好。真正体会到了C++程序员造轮子的乐趣。自己的拼装车就是好用。
文章需要的csv、xls数据文件,大家可以自己从网上下载:
1、网易财经频道可以下载到csv格式的股票日线数据,可以试着用我的quickcsv库读取
2、同花顺股票软件也可以导出xls格式的excel文件,也可以用我的库来读取。
所以,本文就不附加下载内容了,自己找材料测试
今天废话真多,好了,上代码:
QuickCsv.h头文件

#pragma once
#ifndef QUICKCSV_H
#define QUICKCSV_H
#include
#include
#include   
#include 
#include

using namespace std;

class QuickCsv
{
public:
	QuickCsv(std::string Path):mPath(Path)
	{
		//wprintf_s(filename, L"../DaLian.csv");

		//定义为私有函数、放在构造函数里面,更有面向对象编程的意味:实例化一个类对象,就对应一个csv文件的处理
		ReadCsvData();
	}
	~QuickCsv()
	{
		VectorCsvOfAllLines.clear();
	}
	void WriteCsvData()//写csv文件,保存文件
	{

	}
	void DeletRow(int RowID)//删除行
	{

	}
	void DeleteColumn(int ColumnID)//删除列
	{

	}
	void InsertRow(int RowID)//插入行
	{

	}
	void InsertColumn(int ColumnID)//插入列
	{

	}

	
	vector GetColumStrings(int ColumID, bool GetHeader)
	{
		vector VectorCsvRowNames;//保存行名称数据
		for(auto itr= VectorCsvOfAllLines.begin();itr!= VectorCsvOfAllLines.end();++itr)
		{ 
			VectorCsvRowNames.push_back(itr->at(ColumID));
		}
		if (!GetHeader)
		{
			VectorCsvRowNames.erase(VectorCsvRowNames.begin());
		}
		return VectorCsvRowNames;
	}

	
	vector> GetColumsStrings(vector ColumIDs, bool GetHeader)
	{
		vector> VectorCsvRowNames;//保存行名称数据
		vectoroneLine;
		for (auto itr = VectorCsvOfAllLines.begin(); itr != VectorCsvOfAllLines.end(); ++itr)//一大行数据
		{
			for (auto int_itr = ColumIDs.begin(); int_itr != ColumIDs.end(); ++int_itr)//生成的一小行数据
			{
				oneLine.push_back(itr->at(*int_itr));
			}
			VectorCsvRowNames.push_back(oneLine);
			oneLine.clear();
		}
		if (!GetHeader)
		{
			VectorCsvRowNames.erase(VectorCsvRowNames.begin());
		}
		return VectorCsvRowNames;
	}

	//获去csv文件数据的列表表头,
	vector GetHeaders()//读取和处理一行csv数据
	{
		//vectorVectorCsvHeader;
		//ifstream inFile(mPath.c_str(), ios::in); //声明一个ifstream对象,与文件名关联mPath已经构造函数传参
		//string HeaderLineStr;
		//getline(inFile, HeaderLineStr);//不放在while循环里只读取第一行,csv文件的数据表头
		//istringstream sin(HeaderLineStr);         //将整行字符串lineStr读入到字符串流istringstream中
		//string headerDatas;
		把字符串行HeaderLineStr按照字符“,”分割为每一“行”(实际上就是数据块)
		每一个数据块(字符“,"分割的)放入headerDatas
		//while (getline(sin, headerDatas, mch))
		//{
		//	VectorCsvHeader.push_back(Trim(headerDatas));
		//	headerDatas.clear();
		//}
		//HeaderLineStr.clear();
		//return VectorCsvHeader;

		return VectorCsvOfAllLines.at(0);

		
	}

	
	vectorGetRowData(int RowID, bool IsRowName, bool IsHeader)
	{
		if (IsHeader)//为真,存在列头(第0行不是数据);
		{
			RowID += 1;
		}
		//需要判断RowID是否为第0行,有的数据列表没有标头,第0行直接是数据,比如服务器得到的API数据,自己需要按照约定规则的处理
		vector VectorCsvRowDatas;//保存行数据
		vector VectormyLine = VectorCsvOfAllLines.at(RowID);//得到第RowID行

		if (IsRowName)//为真,有行名称;(行的第0项为行名称,不是要计算、比较的数据)
		{
			for (auto itr = VectormyLine.begin() + 1; itr != VectormyLine.end(); ++itr)
			{
				VectorCsvRowDatas.push_back(StringToDouble(*itr));
				//printf_s("%sn",itr->at(0).c_str());
			}
		}
		else//为假,无行名称(行的第0项直接就是数据,比如服务器得到的API数据,自己需要按照约定规则的处理)
		{
			for (auto itr = VectormyLine.begin(); itr != VectormyLine.end(); ++itr)
			{
				VectorCsvRowDatas.push_back(StringToDouble(*itr));
				//printf_s("%sn",itr->at(0).c_str());
			}
		}
		return VectorCsvRowDatas;
	}

	
	vectorGetRowData(int RowID, vectorColumsID, bool IsHeader)
	{
		if (IsHeader)//为真,存在列头(第0行不是数据);
		{
			RowID += 1;
		}
		//需要判断RowID是否为第0行,有的数据列表没有标头,第0行直接是数据,比如服务器得到的API数据,自己需要按照约定规则的处理
		vector VectorCsvRowDatas;//保存行数据
		vector VectormyLine = VectorCsvOfAllLines.at(RowID);//得到第RowID行
		for (auto int_itr = ColumsID.begin(); int_itr != ColumsID.end(); ++int_itr)
		{
			//cout <<"看看  *int_itr的值:"<< * int_itr << endl;
			VectorCsvRowDatas.push_back(StringToDouble(VectormyLine[*int_itr]));
		}
		return VectorCsvRowDatas;
	}
private:
	//定义为私有函数、放在构造函数里面,更有面向对象编程的意味:实例化一个类对象,就对应一个csv文件的处理
	void ReadCsvData()//读取csv文件
	{
		
		vector VectorCsvDataOfOneLine;//csv文件某一行数据项
		ifstream fin(mPath); //打开文件流操作,构造函数传参
		string line;
		//把mPath文件按行整行读取,读取到行line当中,这个行是我们人类所理解的行,以换行符“n”结束。
		//遇到文件尾标志eof终止读取,结束while循环
		while (getline(fin, line))
		{
			//先判断line的格式,即分隔符是什么
			if (line.find(',') != string::npos)//不是以“,”为分隔符
			{
				istringstream sin(line);         //将整行字符串line读入到字符串流istringstream中
				//vector VectorLineStr;           //声明一个字符串向量
				string StrOfOneLine;
				//sin(line)是从文件中读取的一行的数据(回车结束的自然行);
				//StrOfOneLine是从sin(line)中读取一行一行的数据(实际上是数据块),每“行”以字符“,"为分隔符;
				//每“行”字符串(数据块)StrOfOneLine又放入vector当中。
				while (getline(sin, StrOfOneLine, ','))
				{
					VectorCsvDataOfOneLine.push_back(Trim(StrOfOneLine));     //将刚刚读取的每一行的数据块字符串添加到vector中
					line.clear();//看看是否有必要
				}
			}
			else if (line.find('t') != string::npos)//不是以空格“tab”为分隔符
			{
				istringstream sin(line);         //将整行字符串line读入到字符串流istringstream中
				//vector VectorLineStr;           //声明一个字符串向量
				string StrOfOneLine;
				//sin(line)是从文件中读取的一行的数据(回车结束的自然行);
				//StrOfOneLine是从sin(line)中读取一行一行的数据(实际上是数据块),每“行”以字符“,"为分隔符;
				//每“行”字符串(数据块)StrOfOneLine又放入vector当中。
				while (getline(sin, StrOfOneLine, 't'))
				{
					VectorCsvDataOfOneLine.push_back(Trim(StrOfOneLine));     //将刚刚读取的每一行的数据块字符串添加到vector中
					line.clear();//看看是否有必要
				}
			}
			VectorCsvOfAllLines.push_back(VectorCsvDataOfOneLine);
			VectorCsvDataOfOneLine.clear();
			//strtod函数也可以实现string到double的转换
		}
	}

	//整理数据
	string Trim(string& str)
	{
		str.find_first_not_of(" trn");// 在字符串str中从索引0开始,返回首次不匹配"trn"的位置
		str.erase(0, str.find_first_not_of(" trn"));
		str.erase(str.find_last_not_of(" trn") + 1);
		return str;
	}

	
	double StringToDouble(string str)
	{
		assert(str.size() != NULL);//断言非常重要,发现bug
		//if(str.size() == NULL);//断言非常重要,发现bug
		//{
		//	str = "00";
		//}
		int i = 0;
		double dou_num = 0;
		double t = 10;
		bool fh_ = false;

		if (str[i] == '-')
		{
			fh_ = true;
			i++;
		}
		while (str[i] != '')//不是换行符,数据结束符
		{
			if (str[i] == '.')//找到小数点就移位到下一个字符
			{
				i++;//移位到下一个字符
				break;
			}
			dou_num = dou_num * 10 + str[i] - '0';
			i++;
		}
		while (str[i] != '')
		{
			dou_num = dou_num + ((double)str[i] - '0') / t;
			t *= 10;
			i++;
		}
		if (fh_)
			return -1.0 * dou_num;
		else
			return dou_num;
	}
private:
	vector> VectorCsvOfAllLines;//所有的行,包括列表表头、行名称
	wchar_t filename[24];//要打开并读取的csv文件
	std::string mPath;//csv文件的路径,构造函数传参
	int ColumnNum = 0;//csv文件数据的列数,根据表头计算出来
};
#endif // !QUICKCSV_H



调用QuickCsv类的cpp文件

#include"QuickCsv.h"
QuickCsv qc("../shanghai_a.xls");
//QuickCsv qc("../DaLian.csv");

int main()
{
	//调用GetRowNames()函数
	//vector VectorCsvRowNames=qc.GetColumStrings(0,1);//参数为真,把列的表头一项也加进来
	//int i = 0;
	//for (auto itr = VectorCsvRowNames.begin(); itr != VectorCsvRowNames.end(); ++itr)
	//{
	//	printf_s("沪市有%d只股票,第%d只股票代码:%sn", VectorCsvRowNames.size(), i, itr->c_str());
	//	i++;
	//}
	//VectorCsvRowNames.clear();

	//调用GetRowData()函数(一)
	int RowNum =6;
	//vectormRow = qc.GetRowData(RowNum, 1, 1);//第0行的数据
	//for (auto itr = mRow.begin(); itr != mRow.end(); ++itr)
	//{
	//	printf_s("调用GetRowData()函数(一):第%d行有%d项数据:%.5fn", RowNum, mRow.size(), *itr);
	//}
	//mRow.clear();

	调用GetRowData()函数(二)重载
	//vector myColumsID = {3,4, 5 };//我只获取第RowNum行--第2、3、4、5列的数据
	//vectormRow2 = qc.GetRowData(RowNum, myColumsID, 1);//第0行的数据
	//for (auto itr = mRow2.begin(); itr != mRow2.end(); ++itr)
	//{
	//	printf_s("重载调用GetRowData()函数:第%d行有%d项数据:%.5fn", RowNum, mRow2.size(), *itr);
	//}
	//mRow2.clear();			//先进后出
	//myColumsID.clear();		//先进后出


	//调用GetHeaders()函数
	//vectorVectorCsvHeader=qc.GetHeaders();
	//看看效果:
	//int i = 0;
	//for (auto itr = VectorCsvHeader.begin(); itr != VectorCsvHeader.end(); ++itr)
	//{
	//	printf_s("csv文件有%d列;第%d列表头:%sn", VectorCsvHeader.size(), i, itr->c_str());
	//	i++;
	//}
	//VectorCsvHeader.clear();


	vectormyColums = { 0,1,4,7 };//代码、名称、换手率、流通比
	vector> myVector=qc.GetColumsStrings(myColums,1);
	int i = 0;
	for (auto itr = myVector.begin(); itr != myVector.end(); ++itr)
	{
		if (i > 50)
			break;
		//通过itr得到了每一个数据行
		for (auto mitr = itr->begin(); mitr != itr->end(); ++mitr)
		{
			if (mitr != itr->end() - 1)
			{
				printf_s("%s---", mitr->c_str());
			}
			else
			{
				printf_s("%sn", mitr->c_str());
			}
		}
		i++;
	}
	myColums.clear();//先进后出
	myVector.clear();//先进后出


	getchar();

	qc.~QuickCsv();
	return 0;
}

效果图:

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/949898.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号