0

Let's say the input file contains the following, each corresponding with the four members in the struct:
0 2 54 34

1 2 43 56

4 5 32 67

So, for instance, in the first row from the input file, I would want 0 to be stored as a departureStationId, 2 to be stored as arrivalStationId, 54 to be stored as departureTime, and 34 as arrivalTime.

#include <iostream>
#include <fstream>
#include <cstdlib>
#include <list>
#include <vector>
#include <utility>
#include "graph.h"
using namespace std;


int main(int argc, char **argv)
{

  ifstream file;


  struct TrainsFile{ 
    vector<int> departureStationId;
    vector<int> arrivalStationId;
    vector<int> departureTime;
    vector<int> arrivalTime;
  };


  vector<TrainsFile> trains;//creating vector of structs here


  file.open(argv[1]);

  if (file.is_open())
 {
   //How does one use push_back() here given that I am dealing with vectors within vectors?
   while(!file.eof())
   {
    file >> departureStationId >> arrivalStationId >> departureTime >> 
    arrivalTime;
   }

 }
}
coding
  • 9
  • 2
  • 1
    I recommend reconsidering the `TrainsFile` structure. I think you would be better served with `Train` structure that contained a single instance of a train and `vector trains;` Also watch out for [Why is iostream::eof inside a loop condition considered wrong?](https://stackoverflow.com/questions/5605125/why-is-iostreameof-inside-a-loop-condition-considered-wrong) – user4581301 Nov 29 '18 at 20:38

2 Answers2

1

Based on your stated goals and the sample data file, I think you're headed in a bad direction. It appears you want a list of trains in the file, not a list of train files. This makes the vectors inside TrainsFile go away and eliminates your problem.

With a quick re-name of the structure we get

struct Train
{
    int departureStationId;
    int arrivalStationId;
    int departureTime;
    int arrivalTime;
};

and if we move the reading of the file from

while(!file.eof())
{
    file >> departureStationId >> arrivalStationId >> departureTime >> arrivalTime;
}

to an operator>> overload for cleanliness

std::istream &operator >>(std::istream & in, Train & train)
{
    return in >> train.departureStationId 
              >> train.arrivalStationId 
              >> train.departureTime 
              >> train.arrivalTime;
}

we can then rewrite the faulty while loop to

Train train;
while (file >> train)
{
    trains.push_back(train);
}

Which will loop until a train cannot be read from the file.

Fully assembled example:

#include <iostream>
#include <fstream>
#include <vector>
using namespace std;

struct Train
{
    int departureStationId;
    int arrivalStationId;
    int departureTime;
    int arrivalTime;
};

std::istream &operator >>(std::istream & in, Train & train)
{
    return in >> train.departureStationId
              >> train.arrivalStationId
              >> train.departureTime
              >> train.arrivalTime;
}

int main(int argc, char **argv)
{

    ifstream file;

    vector<Train> trains; //creating vector of structs here

    // strongly recommend testing argc to make sure there ID an argv[1] here
    file.open(argv[1]);

    if (file.is_open())
    {
        Train train;
        while (file >> train)
        {
            trains.push_back(train);
        }
    }
}

Since there appears to be one train per line, an improvement to this would be to use std::getline to extract a line from the file and then use a std::istringstream to extract a train from the line. This will allow you to better detect and recover from a malformed file. See Read file line by line using ifstream in C++ for a demonstration of this approach.

user4581301
  • 29,019
  • 5
  • 26
  • 45
0

Create new variables (for reading)

int departureId, arrivalId, departureT, arrivalT;

Inside your loop:

while(file >> departureId >> arrivalId>> departureT >> arrivalT)
{
        TrainsFile trainsfile;
        trainsfile.departureStationId.push_back(departureId);
        trainsfile.arrivalStationId.push_back(arrivalId);
        trainsfile.departureTime.push_back(departureT);
        trainsfile.arrivalTime.push_back(arrivalT);
        trains.push_back(trainsfile);
}//other code

Just need these variables to put in right object,then pushing your main vector

levidone
  • 343
  • 4
  • 16