Edit2 see below, now working but I guess a bit clumsy... perhaps someone knows how to make do without closing and reopening the file.
I have a data file of the following structure (It is a Design Point Matrix for Simulation Analysis):
+----------+----------------------+-----------------+----------+----------+----------+-----------+-------------+
| ConfigID | k_StrategiesPerAgent | K_StrategySpace | l_Lambda | m_Memory | n_Agents | p_crowded | s_Seed |
+----------+----------------------+-----------------+----------+----------+----------+-----------+-------------+
| 0.0 | 0.0 | 0.0 | 0.5 | 12.0 | 10.0 | 0.2 | 353756906.0 |
| 1.0 | 0.0 | 0.2 | 0.5 | 12.0 | 10.0 | 0.2 | 923055597.0 |
| 2.0 | 0.0 | 0.4 | 0.5 | 12.0 | 10.0 | 0.2 | 616881203.0 |
+----------+----------------------+-----------------+----------+----------+----------+-----------+-------------+
ConfigID k_StrategiesPerAgent K_StrategySpace l_Lambda m_Memory n_Agents p_crowded s_Seed
0.0 0.0 0.0 0.5 12.0 10.0 0.2 353756906.0
1.0 0.0 0.2 0.5 12.0 10.0 0.2 923055597.0
2.0 0.0 0.4 0.5 12.0 10.0 0.2 616881203.0
vector<string> Labels; //Hold the parameter labels
vector<double> Parameters; //Hold the parameter values
bool readPars(char * FilePath, int ConfigID); //load the label and value
//return [false] on error, else [true]
for (int i=0;i<Labels.size();i++){
const char * lab = Labels[i].c_str();
double par = Parameters[i];
LSD_MACRO(lab,par)//do something
}
using namespace std;
#include <fstream>
#include <string>
#include <vector>
#include <iterator>
#include <sstream>
#include <iostream>
#include <limits>
int main()
{
ifstream filePL("DPM.tsv"); //Read File in tsv format, with header-line
string label;
getline(filePL, label, '\n');
//Load the string vector with it
istringstream gccNeedsThisOnASeperateLine{ label }; //http://www.cplusplus.com/reference/sstream/istringstream/istringstream/
const vector<string> Labels{ istream_iterator<string>{ gccNeedsThisOnASeperateLine }, istream_iterator<string>{} };
//close file and reopen it, else the first item is skipped.
filePL.close();
ifstream fileP("DPM.tsv"); //Read File in tsv format, with header-line
//Read the remainer and parse it to a 2d vector
vector<vector<double>> Parameters;
int check = 0;
string garbage;
while(fileP.ignore(numeric_limits<streamsize>::max(), '\t')) {
vector<double> input(Labels.size());
for(int i = 0; i < input.size(); i++){
if (check==0){
fileP >> garbage;
} else {
fileP >> input[i];
}
}
if (check>0)
Parameters.push_back(input);
check++;
}
//Test:
for (int i=0;i<Labels.size();i++){
cout << Labels[i] << "\t" << Parameters[0][i] << endl;
}
return 0;
}
Let's talk about your data structures:
double
s otherwise you'll end up with n-copies of the same labels. So we'll put the labels in the container vector<string> Labels
vector<vector<double>> Parameters
and the index will serve as the zero-based key, if not you'll need to use a map<int, vector<double>> Parameters
, since it's simpler we'll assume that the numbers are contiguous and use vector<vector<double>> Parameters
Given that you've successfully opened the file into ifstream fileP
you can get your Labels
like this:
string label;
getline(fileP, label, '\n');
const vector<string> Labels{ istream_iterator<string>{ istringstream{ label } }, istream_iterator<string>{} };
Thought there are fancier methods, we can simply use a nested for
-loop to extract vector<vector<double>> Parameters
:
while(fileP.ignore(std::numeric_limits<std::streamsize>::max(), '\t')) {
vector<double> input(size(Labels) - 1);
for(int i = 0; i < size(input) && fileP >> input[i]; ++i);
Parameters.push_back(input);
}