[英]Read 2D array in CSV into a Map c++
我是CPLEX用户,我需要将CSV文件中的数组数据转换为C ++ 2D Map作为优化问题的输入。 数据显示为列。 也就是说,如果我们考虑3行(AA1,AA2,AA3)和3列(BB1,BB2,BB3)及其各自的值,则它们在CSV文件中具有以下格式:
行,颜色,值
AA1,BB1、0.3
AA2,BB1、0.5
AA1,BB2、0.6
AA1,BB3、0.7
AA2,BB2、0.9
AA3,BB2、0.5
AA3,BB1、0.6
AA2,BB3、0.4
AA3,BB3、0.6
如您所见,数据既不按行也不按列排序。 我希望将数据读取为格式为“ map <字符串,map <字符串,float >> ”的2D Map,以便对生成的map进行排序:
行,颜色,值
AA1,BB1、0.3
AA1,BB2、0.6
AA1,BB3、0.7
AA2,BB1、0.5
AA2,BB2、0.9
AA2,BB3、0.4
AA3,BB1、0.6
AA3,BB2、0.5
AA3,BB3、0.6
任何帮助将不胜感激! 谢谢。
[编辑]行数和列数是预先已知的-无需计数。 我对C ++相对较新(从OPL优化语言迁移),并且对文件操作不是很熟悉。 任何示例代码都将对我理解该过程非常有帮助。
由于您将空格用作分隔字符,因此您应该能够使用标准的<ifstream>
实现来相当快地实现此功能:
#include <ifstream>
#include <string>
#include <map>
#include <iostream>
int main() {
// Open file:
std::ifstream fin("filename.csv"); // Open in text-mode.
// Opening may fail, always check.
if (!fin) {
std::cout << "Error, could not open file." << std::endl;
return -1;
}
// Construct your map.
std::map< std::string, std::map<std::sting, float> > valMap;
// Read the file and load the data:
std::string row, column;
float value;
while ( fin >> row >> column >> value ) { // Reads three values from file.
valMap[row][col] = value; // Adding the values to the map, if the cell is
// a duplicate: It will be overwritten.
}
// Close the file:
fin.close();
// Printing out the data like you described:
for ( auto & columnMap : valMap ) {
for ( auto cell : columnMap.second ) {
std::cout << columnMap->first /*First label*/ << " "
<< cell->first /*Second label*/ << " "
<< cell->second /* Value */ << std::endl;
}
}
return 0;
}
好的,我将在第二个答案中添加它,因为它是解决同一问题的完全不同的方法。
如果可以有许多不同的定界符,则strtok是一个很好的选择。 它最初是C,所以您需要多动一点手,但这是值得的。
char * strtok ( char * str, const char * delimiters );
有两个参数,第一个是我们要分析的字符串,第二个是包含我们要用作定界符的所有不同字符的字符串。
对于您特殊的用例,我将提出以下建议:
#include <cstring>
#include <cstdlib>
#include <string>
#include <fstream>
#include <iostream>
const char * DELIMS = "\t ,"; // Tab, space or comma.
const int MAX_LINE_LENGTH = 1024; // Choose this large enough for your need.
// Or use a dynamic buffer together with
// std::string and getline(istream, string&).
int main() {
std::fstream fin("filename.csv");
// Test for errors
// Prepare a C-string buffer to be used when reading lines.
char buffer[MAX_LINE_LENGTH] = {};
// Prepare map.
std::map< std::string, std::map< std::string, float>> valMap;
// Read one line at a time.
while ( fin.getline(buffer, MAX_LINE_LENGTH) ) {
// Extract the three tokens:
const char * row = strtok( buffer, DELIMS );
const char * col = strtok( NULL, DELIMS );
const char * val = strtok( NULL, DELIMS );
// You could do additional errorchecking here,
// as for instance checking that there are no more valid tokens,
// and that all row, col and val are non-NULL.
// Insert elements.
valMap[std::string(row)][std::string(col)] = std::atof(val);
}
// Cleanup
fin.close();
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.