Search code examples
c++algorithmparsingvectoristringstream

Storing text file into a class


I am currently trying to read in characters into a class that looks like this

 struct data {
    string segment; string name;
    double length; double radius; double wall_thickness;
    double young_modulus; double compliance;

};

I also have a vector that contains the following elements:

  2A
  Aorta_Ascendens
  2
  1.47
  .164
  4
  53.4
  2B
  Aorta_Ascendens
  2
  1.44
  .161
  4
  51.0
  3A

I want to read in the text file into each part, and currently this is my algorithm to continuously read through the text file and add each part respectively.

int place = 0;

        while (place != temp_data.size()){
            int counter = 0;
            for (counter; counter <= 7; ++counter){
                istringstream is(temp_data[place + counter]);

                if (counter == 0){ is >> a.segment; }
                if (counter == 1){ is >> a.name; }
                if (counter == 2){ is >> a.length; }
                if (counter == 3){ is >> a.radius; }
                if (counter == 4){ is >> a.wall_thickness; }
                if (counter == 5){ is >> a.young_modulus; }
                if (counter == 6){ is >> a.compliance; }

            }
            counter = counter - 1;     //since the next segment is at    temp_data[7], must subtract one to have place = 7.
            place = counter + place;

            v.push_back(a);
        }

The problem I ran into is trying to find a way to make sure the right part of the text goes into the right part of the object. for the first seven lines of text the object should be like this :

segment: 2A
name: Aorta_Ascendens
length: 2
radius: 1.47
wall_thickness: .164
young modulus: 4
compliance: 53.4

This should repeat the same way for the whole of the text file. temp_data is a vector that holds the elements that need to be added into the object, but I cant find a good way to continually cycle through the vector and put the elements into the right place.

The algorithm I made has a counter and a place holder, the counter would cycle through the vector points and the place holder would hold spot for the first object's data member, in this case segment. At the end of the algorithm, place should equal the size of temp_data and get out of the loop. But I am having a problem when it compiles and runs, it seems to be putting the wrong element into the wrong object member.

Any ideas?


Solution

  • A simple, clean way to approach this is to write a custom streaming operator:

    struct data {
        string segment; string name;
        double length; double radius; double wall_thickness;
        double young_modulus; double compliance;
    
        friend std::istream& operator>>(std::istream& is, data& d)
        {
            return is >> d.segment >> d.name >> d.length >> d.radius >> d.wall_thickness
                      >> d.young_modulus >> d.compliance;
        }
    };
    

    No temp_data, istringstream or counter.

    To use this:

    data d;
    while (input_stream >> d)
        v.push_back(d);
    if (input_stream.fail())
        ...print error / exit or whatver...
    else
        ...use v...
    

    (There are more declarative ways to use Standard algorithms and back_inserter iterators to copy from the stream to the vector, but IMHO simple and obvious is good)