c++ 读文本,格式如下 |
|
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; } 调试结果如下: |
|
感谢你的帮助,其实我是写完底层用在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; } 调试结果图: |
|
想要的初步效果如下, 文本格式如 adsasdafdasfd // 标题 3 // 变量个数 time yaxis xaxis // 变量 1 2 3 // 数据 4 5 6 7 8 9 10 11 12 // 空格 最后一行是空格,就是12后面再按一次回车键,请各位大神帮忙看看啊 |
|
嗯,可用map调试时发现没按顺序存储,后面在mfc上操作时怎么点击变量就能索引其数据呢? 第17行没有问题吗?我直接复制过去放在控制台里不管运行? 大神们可否提供下思路怎么做顶层界面的东西,就是选择变量名就可以提取里面的数据进行比如加法运算之类的,谢谢了 |
|
5分 |
map会按key自动排序的
|
那怎么检索呢?才能根据string得到对应的数据? |
|
5分 |
你的数据不是已经保存为形如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)); } |