Thread: Read several files of the same line into an struct vector

  1. #1
    Registered User
    Join Date
    Feb 2018
    Posts
    7

    Read several files of the same line into an struct vector

    Hi guys, first post here, I will appreciate all the insight I can get on this problem.

    I am working on a sort of big project where I get to do some mathematical simulation of some variables and compared to their original values which I have as input from a file.

    I have about 5 text files with the same number of lines, but different types of values in them, and I am trying to read each of the lines into a struct, then make a vector of the struct so that I can loop through each line of the files to get my computational values. e.g

    My main question is that i want to loop over each line of four input files with an equal number of rows and columns, get a set of values from the line, solve some differential equations, and get a value unique to each line.


    Code:
    struct Inp
    {
        int i, j;
        double Iij;
        double ton, toff;
    };
    
    istream& operator >> (istream &is, Inp &s)
    {
        string line;
        getline(is, line);
        istringstream ss(line);
        ss >> s.i >> s.j >> s.Iij >> s.ton >> s.toff ;
        return is;
    }
    
    vector<Inp> Xdata;
    I have four files with 30 lines each, one of these files has the actual value of my variable. So I am trying to store the entire lines of the files in a vector so that for each line, I can calculate my unknown variable and compare the result to its actual value.

    These are the example of some of my files:

    inp.dat
    1 2 1.24 1.2 1.7
    1 3 1.44 0.3 1.4
    1 1 1.14 1.4 1.5
    1 4 1.04 1.13 1.5
    X_actual.dat
    1.02 2.0 1.24 1.2 1.7
    1.42 3.2 1.44 0.3 1.4
    1.32 1.3 1.14 1.4 1.5
    1.44 4.1 1.04 1.13 1.5

    Time.dat
    0.1 2.3 1.24 1.2 1.7
    1.3 3.2 1.44 0.3 1.4
    2.5 1.0 1.14 1.4 1.5
    1.5 4.2 1.04 1.13 1.5
    The Inp and Time are variables I will be needing to calculate my initial variable.
    Last edited by Siorac; 02-28-2018 at 08:18 PM.

  2. #2
    Registered User
    Join Date
    Dec 2017
    Posts
    867
    You haven't actually asked a question! Are you asking how to use your overloaded insertion operator to read new structs into your vector?

    I'm no C++ expert, but maybe something like this.
    Code:
    #include <iostream>
    #include <fstream>
    #include <string>
    #include <vector>
    using namespace std;
    
    struct Inp;
    
    istream& operator>>(istream &is, Inp &s);
    
    struct Inp {
        int i, j;
        double Iij;
        double ton, toff;
    
        Inp(istream& is) {
            if (!(is >> *this))
                throw 1;
        }
    };
    
    istream& operator >> (istream &is, Inp &s) {
        return is >> s.i >> s.j >> s.Iij >> s.ton >> s.toff;
    }
    
    ostream& operator << (ostream &os, const Inp &s) {
        return os << s.i <<' '<< s.j <<' '<<
                     s.Iij <<' '<< s.ton <<' '<< s.toff;
    }
    
    int main() { 
        vector<Inp> Xdata;
    
        ifstream ifs("inp.dat");
        try {
            while (true)
                Xdata.push_back(Inp(ifs));
        } catch (...) {
            ifs.close();
        }
    
        for (const auto x: Xdata)
            cout << x << '\n';
    }
    The world hangs on a thin thread, and that is the psyche of man. - Carl Jung

  3. #3
    Registered User
    Join Date
    Feb 2018
    Posts
    7
    Hey @John.c I have four input files with the same number of rows and columns, i want to loop over each line of the four files to get values to solve the equation in a model. Do you understand the question now?

  4. #4
    Registered User
    Join Date
    Feb 2018
    Posts
    7
    Thanks, @john.c, I have edited my question now.

  5. #5
    Registered User
    Join Date
    Jun 2017
    Posts
    156
    Slightly different approach - code based on john.c

    Code:
    #include <iostream>
    #include <fstream>
    #include <string>
    #include <vector>
    
    using namespace std;
    
    struct Inp 
    {
      int i, j;
      double Iij;
      double ton, toff;
    };
    
    istream& operator >> (istream &is, Inp &s) 
    {
      return is >> s.i >> s.j >> s.Iij >> s.ton >> s.toff;
    }
    
    ostream& operator << (ostream &os, const Inp &s) 
    {
      return os << s.i << ' ' << s.j << ' ' 
                << s.Iij << ' ' << s.ton << ' ' << s.toff;
    }
    
    int main() 
    {
      vector<Inp> Xdata;
    
      ifstream ifs("inp.dat");
      if (!ifs)
      {
        cerr << "Error opening file...";
        return 1;
      }
      Inp tmp;
      while (ifs >> tmp)
      {
        Xdata.push_back(tmp);
      }
    
      for (const auto x : Xdata)
      {
        cout << x << '\n';
      }
    }

  6. #6
    Registered User
    Join Date
    Feb 2018
    Posts
    7
    Hi, I have done this for one file, however, I will like to do the same for all four files, and into the same vector.

  7. #7
    Registered User
    Join Date
    Dec 2017
    Posts
    867
    Quote Originally Posted by Siorac View Post
    Hi, I have done this for one file, however, I will like to do the same for all four files, and into the same vector.
    In what sense do you want them to be "in the same vector"? You could mean two things. Demonstrating with just 2 files:
    Code:
    a.txt:
    1 2 3 4 5
    6 7 8 9 0
    
    b.txt:
    0 9 8 7 6
    5 4 3 2 1
    You could want to append all the lines of all the files to the vector. All your files would have to have the same number of fields of the same (or compatible) type to do that, but the samples you've shown so far are compatible. So the above files would give you 4 rows in the vector:
    Code:
    1 2 3 4 5
    6 7 8 9 0
    0 9 8 7 6
    5 4 3 2 1
    Or you could want to add corresponding lines of each of the files to the same vector row. So the above files would give you just 2 rows in the vector:
    Code:
    1 2 3 4 5 0 9 8 7 6
    6 7 8 9 0 5 4 3 2 1
    That would require adding fields to the struct.
    The world hangs on a thin thread, and that is the psyche of man. - Carl Jung

  8. #8
    Registered User
    Join Date
    Dec 2017
    Posts
    867
    Here's a way to do the first option. (Using OldGuy2's tmp technique to avoid the exception handling ... and testing that the files actually open ...)
    Code:
    #include <iostream>
    #include <fstream>
    #include <string>
    #include <vector>
    using namespace std;
    
    struct Data
    {
      int i, j;
      double Iij, ton, toff;
    };
    
    istream& operator >> (istream &is, Data &s)
    {
      return is >> s.i >> s.j >> s.Iij >> s.ton >> s.toff;
    }
     
    ostream& operator << (ostream &os, const Data &s) 
    {
      return os << s.i << ' ' << s.j << ' '
                << s.Iij << ' ' << s.ton << ' ' << s.toff;
    }
     
    int main() 
    {
      const char *input_files[] = {
          "a.txt", "b.txt", "c.txt", NULL
      };
      vector<Data> data;
    
      for (int i = 0; input_files[i]; i++) 
      {
        ifstream ifs(input_files[i]);
        if (!ifs)
        {
          cerr << "Error opening file: " << input_files[i] << '\n';
          return 1;
        }
    
        Data tmp;
        while (ifs >> tmp)
        {
          data.push_back(tmp);
        }
      } 
    
      for (const auto& d : data)
      {
        cout << d << '\n';
      }
    }
    The world hangs on a thin thread, and that is the psyche of man. - Carl Jung

  9. #9
    Registered User
    Join Date
    Feb 2018
    Posts
    7
    Hello, John.c,

    So here is the dilemma, I don't necessarily have to use structs as it is my own model and my implementation is left for me to decide.

    The thing I want to achieve is this, say I have 4 files with the same number of rows and columns, each row entry is unique from one file to another, say:

    a.txt
    1 2.1 3.3 4.5 2
    1 1.2 3.3 4.5 2
    1 0.8 3.3 4.5 2
    b.txt
    2 1 2 0.3 4.5 2.5
    2 1 3 1.3 4.5 2.2
    2 1 4 2.3 4.5 2.3
    For the model I am trying to solve, in file b.txt, the first entry on each line is a vector size, and the second and third are the values that should go into the vector.

  10. #10
    Registered User
    Join Date
    Dec 2017
    Posts
    867
    Nope. I still don't get it. Sorry.
    Maybe you should explain the whole thing and show sample data from every file and tell us what you want to do with it.
    The world hangs on a thin thread, and that is the psyche of man. - Carl Jung

  11. #11
    Registered User
    Join Date
    Dec 2017
    Posts
    867
    You say the files have 30 lines each. Do you have 30 values to calculate? Do you need a line from each file for each calculation?
    The world hangs on a thin thread, and that is the psyche of man. - Carl Jung

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 2
    Last Post: 05-10-2017, 08:30 PM
  2. Replies: 21
    Last Post: 08-07-2011, 09:55 PM
  3. Read text file line by line and write lines to other files
    By magische_vogel in forum C Programming
    Replies: 10
    Last Post: 01-23-2011, 10:51 AM
  4. C Term Project( struct, read files) Please Help
    By bttf in forum C Programming
    Replies: 3
    Last Post: 05-29-2007, 03:31 AM
  5. How to read files into a struct
    By verbity in forum C Programming
    Replies: 16
    Last Post: 11-24-2006, 03:39 PM

Tags for this Thread