Code Bye

c++ 读文本,格式如下

c++ 读文本,格式如下
var1 var2 var3 var4  ….
data1 data2 data3 data4…
data  data data data
….
….
….
即第一行是变量名,个数未知,下面都是数据行,现在想按照列来存储数据,即每个变量名对应一列数据,想用动态数组或向量来写,map〈string,vector〈double〉〉mapVec来寸,即一个var对应一组data,请问各位大神怎样随着列的变化来动态申请vetor〈double〉来存储数据呢?我现在已经动态申请二维数组实现了数据的存储,但是怎样与变量名对应起来不知如何去弄了,恳请各位大神支招,我是先一行一行读文本,然后按列把数据存在不同的doubleVec里,比如有3个变量即3列数据,我可以申请 vector<double>doubleVec1,doubleVec2,doubleVec3;一行一行读,把每行的数据的每一列分别存在doubleVec1,doubleVec2,doubleVec3里,最后再mapVec[var1] = doubleVec1,mapVec[var2] = doubleVec2,mapVec[var3] = doubleVec3,这样就可以实现一个变量名对应一列数据以供以后使用。关键问题是现在变量个数未知,不可能初始化N个存储数据的容器,怎样根据变量数也就是列数来动态申请存储变量数据的容器呢?和变量名一一对应,当然大神们也可以提供其他方法,谢谢了

5分
先用一个vector<string>存变量名
读完第一行后根据变量数量往一个vector<vector<double>>里塞vector<double>来存每一列的数据
每行就分别取出每一个vector<double>然后存数据进去
最后再用两个vector建立map
20分
奔跑吧,参考:
#include <iostream>
#include <fstream>
#include <vector>
using namespace std;
int main(void)
{
	fstream fin;
	fin.open("1.txt", ios::in);
	if (!fin.is_open())
	{
		cerr << "can not open file 1.txt" << endl;
		return 1;
	}
	vector < pair< string, vector<double> > > vars;
	string s;
	//读入变量名称行
	getline(fin, s);
	int i, j, start = 0;
	for (i = 0; i < s.size(); i++)
	{
		if ("" "" == s[i])
		{
			vector<double> vec;
			vars.push_back(make_pair(string(s, start, i - start), vec));
			start = i + 1;
		}
	}
	if ("" "" != s[i])
	{
		vector<double> vec;
		vars.push_back(make_pair(string(s, start, i - start), vec));
	}
	double d;
	//读入参数
	while (!fin.eof())
	{ 
		for (i = 0; i < vars.size(); i++)
		{
			fin >> d;
			vars[i].second.push_back(d);
		}
	}
	//打印
	for (i = 0; i < vars.size(); i++)
	{
		cout << vars[i].first << " : ";
		for (j = 0; j < vars[i].second.size(); j++)
		{
			cout << vars[i].second[j] << ends;
		}
		cout << endl;
	}
	fin.close();
	return 0;
}
var1 var2 var3 var4 var5 var6
1.1 2.2 3.3 4.4 5.5 6.6
1.1 2.2 3.3 4.4 5.5 6.6
1.1 2.2 3.3 4.4 5.5 6.6
1.1 2.2 3.3 4.4 5.5 6.6
1.1 2.2 3.3 4.4 5.5 6.6

你把你不知道多少个的部分也做成容器保存
5分
把一条数据做成一个结构体,第一行读到多少条数据,就在vector里面push多少个结构,下面的data数据,则依次vector修改里面值就可以了
感谢你的帮助,其实我是写完底层用在MFC上,效果就是读文件后然后把变量名和数据一一对应起来,然后把变量名显示在ListBox控件上(初步这么打算),然后选择列表框控件里的变量就可以抽取其数据进行各种运算,比如加法之类的,附上我的读文件代码,大神帮忙看看,用map时,变量存的顺序发生变化,不知什么原因,猜想是不是map不是顺序容器造成的,应该怎么解决呢?
BOOL ReadFile(std::string& strDataPathName,std::map<std::string,std::vector<double> >&MapVec,std::string& errString)
{
	std::ifstream ifsData;
	if (strDataPathName.empty())
	{
		errString = "文件为空,请先选择数据文件!";
			return FALSE;
	}

	// 以文本形式打开文件
	ifsData.open(strDataPathName.c_str());
	if (!ifsData.is_open())
	{
		errString = "文件打开错误";
		ifsData.close();
		return FALSE;
	}

	const int strTitleSize = 256;      // 设置标题行最大字节数为256
	const int strDataSize  = 256;      // 设置每个数据对应的最大字节数

	char VarCountBuf[strTitleSize];

	// 跳过标题行
	memset(VarCountBuf,0,256);
	ifsData.getline(VarCountBuf,256);
	memset(VarCountBuf,0,256);

	// 读取变量个数
	ifsData.getline(VarCountBuf,256);
	int nVarCount = (int)atoi(VarCountBuf);  

	if (nVarCount <= 0)
	{
		errString = "变量名读取错误";
		ifsData.close();
        return FALSE;
	}

	// 读取变量名 
	const int lineDataSize = nVarCount*strDataSize;    // 设置变量名行及数据行所在行最大字节数
    char* varNameBuf = new char[lineDataSize];        // 动态申请变量名存储空间

	memset(varNameBuf,0,lineDataSize);
	ifsData.getline(varNameBuf,lineDataSize);

	std::string tmpString = varNameBuf;              // 变量名字符串临时存放变量
	delete []varNameBuf;

	std::string* strVarName = new std::string[nVarCount];   // 根据变量名个数申请变量存放数组
	strVarName->clear();

	// 变量名格式转换
	int nVarLoop = nVarCount;
	int i = 0;
	int indexVarName1 = 0;
	int indexVarName2 = 0;

	while(nVarLoop > 0)
	{
		while (-1 != indexVarName1)
		{
			indexVarName1 = tmpString.find(" ",indexVarName2);

			if(0 == indexVarName1)
			{
				errString = "变量名解析错误";
				ifsData.close();
				return FALSE;
			}
			strVarName[i] = tmpString.substr(indexVarName2,indexVarName1-indexVarName2);
			indexVarName2 = indexVarName1 + 1;
			i++;
			nVarLoop--;
		}
		break;
	}

	if(nVarLoop > 0)
	{
		errString = "变量名个数不匹配";
		ifsData.close();
		return FALSE;
	}

	// 记录遍历变量名后的指针位置
	const __int64 DataOffset = ifsData.tellg().seekpos();

	// 遍历整个文件,计算数据行数
	int nlineCount = 0;
	char* dataInfoBuf = new char[lineDataSize];
	memset(dataInfoBuf,0,lineDataSize);

	while(!ifsData.eof())
	{
		ifsData.getline(dataInfoBuf,lineDataSize);
		nlineCount++;
	}
	nlineCount = nlineCount - 1;        // 文件最后一行为空


	// 动态申请二维数组用以存储数据 行*列,即nLineCount*nVarCount
// 	double** pData = new double*[nlineCount];
// 	for(int i = 0;i < nlineCount;i++ )
// 	{
// 		pData[i] = new double[nVarCount];
// 		memset(pData[i],0,nVarCount*sizeof(double));
// 	}

	// 返回数据开始位置
	ifsData.clear();
	ifsData.seekg(DataOffset);

	// 申请数据存储空间
	typedef std::vector<double> doubleVec;
	/*std::map <std::string,doubleVec> MapVec;*/
	doubleVec* dataVec = new doubleVec [nVarCount];
	dataVec->clear();
	MapVec.clear();


// 	std::string* strVarData = new std::string[nVarCount];   // 动态申请数据字符数组
// 	strVarData->clear();

	memset(dataInfoBuf,0,lineDataSize);

	// 二维数组存储数据
	int nLoopRow = 0;
	int nLoopColumn = 0;
	while(nLoopRow < nlineCount)
	{
		ifsData.getline(dataInfoBuf,lineDataSize);
		nLoopColumn = 0;
		std::string strDataTemp = dataInfoBuf;
		int indexData1 = 0;
		int indexData2 = 0;
		int nReadLoop = nVarCount;
		while (nReadLoop > 0)
		{
			indexData1 = strDataTemp.find(" ",indexData2);
			if (0 == indexData1)
			{
				errString = "数据解析错误";
				ifsData.close();
				return FALSE;
			}
			dataVec[nLoopColumn].push_back(stof(strDataTemp.substr(indexData2,indexData1-indexData2)));
			/*dataVec.push_back(pData[nLoopRow][nLoopColumn]);*/
			MapVec[(strVarName[nLoopColumn])] = dataVec[nLoopColumn];

			indexData2 = indexData1 + 1;
			nLoopColumn++;
			nReadLoop--;
		}
		nLoopRow++;
	}

	delete[]strVarName;
	delete[]dataInfoBuf;
	delete[]dataVec;

	// 释放二维数组空间
// 	for(int i = 0;i < nlineCount;i++)
// 		delete [] pData[i];
// 	delete [] pData;

	ifsData.close();
	return TRUE;
}

调试结果如下:

引用 2 楼 zhangxiangDavaid 的回复:

奔跑吧,参考:

#include <iostream>
#include <fstream>
#include <vector>
using namespace std;
int main(void)
{
	fstream fin;
	fin.open("1.txt", ios::in);
	if (!fin.is_open())
	{
		cerr << "can not open file 1.txt" << endl;
		return 1;
	}
	vector < pair< string, vector<double> > > vars;
	string s;
	//读入变量名称行
	getline(fin, s);
	int i, j, start = 0;
	for (i = 0; i < s.size(); i++)
	{
		if ("" "" == s[i])
		{
			vector<double> vec;
			vars.push_back(make_pair(string(s, start, i - start), vec));
			start = i + 1;
		}
	}
	if ("" "" != s[i])
	{
		vector<double> vec;
		vars.push_back(make_pair(string(s, start, i - start), vec));
	}
	double d;
	//读入参数
	while (!fin.eof())
	{ 
		for (i = 0; i < vars.size(); i++)
		{
			fin >> d;
			vars[i].second.push_back(d);
		}
	}
	//打印
	for (i = 0; i < vars.size(); i++)
	{
		cout << vars[i].first << " : ";
		for (j = 0; j < vars[i].second.size(); j++)
		{
			cout << vars[i].second[j] << ends;
		}
		cout << endl;
	}
	fin.close();
	return 0;
}
var1 var2 var3 var4 var5 var6
1.1 2.2 3.3 4.4 5.5 6.6
1.1 2.2 3.3 4.4 5.5 6.6
1.1 2.2 3.3 4.4 5.5 6.6
1.1 2.2 3.3 4.4 5.5 6.6
1.1 2.2 3.3 4.4 5.5 6.6

感谢你的帮助,其实我是写完底层用在MFC上,效果就是读文件后然后把变量名和数据一一对应起来,然后把变量名显示在ListBox控件上(初步这么打算),然后选择列表框控件里的变量就可以抽取其数据进行各种运算,比如加法之类的,附上我的读文件代码,大神帮忙看看,用map时,变量存的顺序发生变化,不知什么原因,猜想是不是map不是顺序容器造成的,应该怎么解决呢?

BOOL ReadFile(std::string& strDataPathName,std::map<std::string,std::vector<double> >&MapVec,std::string& errString)
{
	std::ifstream ifsData;
	if (strDataPathName.empty())
	{
		errString = "文件为空,请先选择数据文件!";
			return FALSE;
	}

	// 以文本形式打开文件
	ifsData.open(strDataPathName.c_str());
	if (!ifsData.is_open())
	{
		errString = "文件打开错误";
		ifsData.close();
		return FALSE;
	}

	const int strTitleSize = 256;      // 设置标题行最大字节数为256
	const int strDataSize  = 256;      // 设置每个数据对应的最大字节数

	char VarCountBuf[strTitleSize];

	// 跳过标题行
	memset(VarCountBuf,0,256);
	ifsData.getline(VarCountBuf,256);
	memset(VarCountBuf,0,256);

	// 读取变量个数
	ifsData.getline(VarCountBuf,256);
	int nVarCount = (int)atoi(VarCountBuf);  

	if (nVarCount <= 0)
	{
		errString = "变量名读取错误";
		ifsData.close();
        return FALSE;
	}

	// 读取变量名 
	const int lineDataSize = nVarCount*strDataSize;    // 设置变量名行及数据行所在行最大字节数
    char* varNameBuf = new char[lineDataSize];        // 动态申请变量名存储空间

	memset(varNameBuf,0,lineDataSize);
	ifsData.getline(varNameBuf,lineDataSize);

	std::string tmpString = varNameBuf;              // 变量名字符串临时存放变量
	delete []varNameBuf;

	std::string* strVarName = new std::string[nVarCount];   // 根据变量名个数申请变量存放数组
	strVarName->clear();

	// 变量名格式转换
	int nVarLoop = nVarCount;
	int i = 0;
	int indexVarName1 = 0;
	int indexVarName2 = 0;

	while(nVarLoop > 0)
	{
		while (-1 != indexVarName1)
		{
			indexVarName1 = tmpString.find(" ",indexVarName2);

			if(0 == indexVarName1)
			{
				errString = "变量名解析错误";
				ifsData.close();
				return FALSE;
			}
			strVarName[i] = tmpString.substr(indexVarName2,indexVarName1-indexVarName2);
			indexVarName2 = indexVarName1 + 1;
			i++;
			nVarLoop--;
		}
		break;
	}

	if(nVarLoop > 0)
	{
		errString = "变量名个数不匹配";
		ifsData.close();
		return FALSE;
	}

	// 记录遍历变量名后的指针位置
	const __int64 DataOffset = ifsData.tellg().seekpos();

	// 遍历整个文件,计算数据行数
	int nlineCount = 0;
	char* dataInfoBuf = new char[lineDataSize];
	memset(dataInfoBuf,0,lineDataSize);

	while(!ifsData.eof())
	{
		ifsData.getline(dataInfoBuf,lineDataSize);
		nlineCount++;
	}
	nlineCount = nlineCount - 1;        // 文件最后一行为空


	// 动态申请二维数组用以存储数据 行*列,即nLineCount*nVarCount
// 	double** pData = new double*[nlineCount];
// 	for(int i = 0;i < nlineCount;i++ )
// 	{
// 		pData[i] = new double[nVarCount];
// 		memset(pData[i],0,nVarCount*sizeof(double));
// 	}

	// 返回数据开始位置
	ifsData.clear();
	ifsData.seekg(DataOffset);

	// 申请数据存储空间
	typedef std::vector<double> doubleVec;
	/*std::map <std::string,doubleVec> MapVec;*/
	doubleVec* dataVec = new doubleVec [nVarCount];
	dataVec->clear();
	MapVec.clear();


// 	std::string* strVarData = new std::string[nVarCount];   // 动态申请数据字符数组
// 	strVarData->clear();

	memset(dataInfoBuf,0,lineDataSize);

	// 二维数组存储数据
	int nLoopRow = 0;
	int nLoopColumn = 0;
	while(nLoopRow < nlineCount)
	{
		ifsData.getline(dataInfoBuf,lineDataSize);
		nLoopColumn = 0;
		std::string strDataTemp = dataInfoBuf;
		int indexData1 = 0;
		int indexData2 = 0;
		int nReadLoop = nVarCount;
		while (nReadLoop > 0)
		{
			indexData1 = strDataTemp.find(" ",indexData2);
			if (0 == indexData1)
			{
				errString = "数据解析错误";
				ifsData.close();
				return FALSE;
			}
			dataVec[nLoopColumn].push_back(stof(strDataTemp.substr(indexData2,indexData1-indexData2)));
			/*dataVec.push_back(pData[nLoopRow][nLoopColumn]);*/
			MapVec[(strVarName[nLoopColumn])] = dataVec[nLoopColumn];

			indexData2 = indexData1 + 1;
			nLoopColumn++;
			nReadLoop--;
		}
		nLoopRow++;
	}

	delete[]strVarName;
	delete[]dataInfoBuf;
	delete[]dataVec;

	// 释放二维数组空间
// 	for(int i = 0;i < nlineCount;i++)
// 		delete [] pData[i];
// 	delete [] pData;

	ifsData.close();
	return TRUE;
}

调试结果图:

引用 2 楼 zhangxiangDavaid 的回复:

奔跑吧,参考:

想要的初步效果如下,

文本格式如

adsasdafdasfd                     // 标题
3                                              // 变量个数
time yaxis xaxis                   // 变量
1 2 3                                      // 数据
4 5 6
7 8 9
10 11 12                                
                                               // 空格

最后一行是空格,就是12后面再按一次回车键,请各位大神帮忙看看啊

引用 1 楼 iyomumx 的回复:

先用一个vector<string>存变量名
读完第一行后根据变量数量往一个vector<vector<double>>里塞vector<double>来存每一列的数据
每行就分别取出每一个vector<double>然后存数据进去
最后再用两个vector建立map

嗯,可用map调试时发现没按顺序存储,后面在mfc上操作时怎么点击变量就能索引其数据呢?

引用 2 楼 zhangxiangDavaid 的回复:

奔跑吧,参考:

第17行没有问题吗?我直接复制过去放在控制台里不管运行?

引用 4 楼 xdayong 的回复:

把一条数据做成一个结构体,第一行读到多少条数据,就在vector里面push多少个结构,下面的data数据,则依次vector修改里面值就可以了

引用 4 楼 xdayong 的回复:

把一条数据做成一个结构体,第一行读到多少条数据,就在vector里面push多少个结构,下面的data数据,则依次vector修改里面值就可以了

大神们可否提供下思路怎么做顶层界面的东西,就是选择变量名就可以提取里面的数据进行比如加法运算之类的,谢谢了

5分
map会按key自动排序的
引用 10 楼 u012071890 的回复:

map会按key自动排序的

那怎么检索呢?才能根据string得到对应的数据?

5分
引用 11 楼 shuyunyu 的回复:
Quote: 引用 10 楼 u012071890 的回复:

map会按key自动排序的

那怎么检索呢?才能根据string得到对应的数据?

你的数据不是已经保存为形如std::map<std::string,std::vector<double> >的数据结构了么?那么list的显示就是取map的所有key进行列表显示,点击某列表项,根据相应的key去map中find不就是对应此key的值列表std::vector<double>么。


if ("" "" != s[i])
    {
        vector<double> vec;
        vars.push_back(make_pair(string(s, start, i - start), vec));
    }  代码有问题
应该
if ("" "" != s[i-1])
    {
        vector<double> vec;
        vars.push_back(make_pair(string(s, start, i - start), vec));
    }

CodeBye 版权所有丨如未注明 , 均为原创丨本网站采用BY-NC-SA协议进行授权 , 转载请注明c++ 读文本,格式如下