Gray
Gray

Reputation: 491

c++ How to make multidimentional vector from a table in a text file?

I want to store the following table to a multidimentional vector in c++ so that I can call the value by the column names. Here is my table:

  1 #kjflsj sjflskjf
  2 100.00 200.43
  3 101.23 198.56
  4 102.12 201.87
  5 99.67 198.28
  6 #sfjslkdjf lsfjls jf jslkfjsij osiioj o
  7 100.54 205.98
  8 99.87 199.34
  9 101.57 202.75
 10 103.10 193.50
 11 101.78 198.33
 12 102.13 204.75
 13 #slifjsf ojfosij  oiuiso  joij
 14 104.56 208.34
 15 106.14 199.50
 16 105.98 200.00

And here are my codes:

 16     ifstream myfile;
 17     myfile.open (arguments[1]);
 18     string line;
 19     string sline;
 20     vector< vector<double> > values;
 21     double x;

 24 if (myfile.is_open())
 25     {
 26         getline(myfile, sline);
 27         cout << sline << endl;
 28         while (!myfile.eof())
 29         {
 30             if(line.at(0) != '#')
 31             {
 32                 myfile >> x;
 33                 values.push_back(vector<double>(x));
 34
 35                 for(int count = 0; count < values.size(); count++)
 36                 {
 37                     values.push_back( vector<double>(count) );
 38                     cout << values.at(0).at(0);
 39                 }
 40             }
 41         }
 42     }else cout << "The file doesn't exist" << endl;
 43 }

The error I got:

terminate called after throwing an instance of 'std::out_of_range'
  what():  basic_string::at
Aborted (core dumped)

Any ideas?

Upvotes: 0

Views: 765

Answers (1)

Barry
Barry

Reputation: 303711

The cause of the exception is likely:

getline(myfile, sline);   // <== reading into "sline"
while (!myfile.eof())
{
    if(line.at(0) != '#') // <== checking "line"
    {

You're reading into one string, but checking the wrong one!

The correct check would be:

while (getline(myfile, sline)) {
    if (sline.at(0) != '#') {
        // note that before, for non-commented lines, you
        // just dropped sline completely, and went back to the
        // file for input. That is wrong, you need to 
        // parse the line you just got!

        std::vector<double> next_row;
        std::istringstream iss(sline);
        while (iss >> x) {
            next_row.push_back(x);
        }

        // etc.
    }
}

Once that is fixed, it's not obvious, but this loop:

for(int count = 0; count < values.size(); count++)
{
    values.push_back( vector<double>(count) );
    cout << values.at(0).at(0);
}

is actually an infinite loop if values is non-empty. This is because on every iteration, we insert an element into values, which increases its size. So both count and values.size() increment by one every iteration - you're constantly moving the goal posts. That is a serious logical error.

Upvotes: 1

Related Questions