ifstream selectively read in information

If I have a data file.dat like this, for example:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
...
other information
...
physics:
4,5,6,7
...

line:
(4,2), (2,4)

line:
(1,2), (2,3)

...
...


I want to design a class and corresponding code so that every time when it reads "line:" for the file.dat , it will push_back a new line into the line_t vector, and each time when it encounter physics it will put the values to physics, How can I implement this?

every data in file.dat is useful, they need to be read into different class type. How can I implement this?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
class line_t {
public:
    vector<point_t> P(2, point_t());


    line_t(ifstream )???
    ifstream operator >> (ifstream & ifs, line_t L)??? which one? how?

}

class physics {
public:
    double a,b,c,d;
}

int main() {
    ifstream ifs="file.dat";
    if(ifs read "line:") {???}
    if(ifs read "physcis:") {???}

    return 0;
}



Well for starts, your main() could look like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#include <iostream>
#include <ifstream>
#include <string>

using namespace std;

int main()
{
    ifstream ifs = "file.dat";
    string myLine;
    
    while(!ifs.eof())          //read file to the end
    {
        getline(ifs, myLine);
        
        if(myLine == "physics:")
        {
            // do stuff here
        }
        else if(myLine == "line:")
        {
            // other stuff here
        }
    }
    
    return 0;
}


As to how to implement reading line_t and point_t objects, I suggest reading http://www.cplusplus.com/reference/string/stoi/ and http://www.cplusplus.com/reference/string/string/substr/ on this website. Those are string functions; stoi means "string to integer", which could be useful to you... because basically this is what you're gonna have to do, read each line into a string, and then convert its content to whatever format your classes will have... I don't see the point in overloading any operator here, I think getline() will suffice, only design a function that will convert each string into a line_t or point_t object, that you can then push_back in a vector... it's getting late, so let me know if you're still stuck after this so I can give you some more advice.

Cheers,
AeonFlux1212
Last edited on
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#include <iostream>
#include <ifstream>
#include <string>
#include "myClasses.h"

using namespace std;

int main()
{
    physics Fizz;
    line_t line;
    ifstream ifs = "file.dat";
    string myLine;
    
    while(!ifs.eof()getline(ifs, myLine))       // better to read file like this

    {
        getline(ifs, myLine);
        
        if(myLine == "physics:")
        {
            // do stuff here
            double a,b,c,d;
            //extract values
            Fizz.setVals(a,b,c,d);
        }
        else if(myLine == "line:")
        {
            // other stuff here
           
        }
    }
    
    return 0;
}
Last edited on
> every data in file.dat is useful, they need to be read into different class type. How can I implement this?

Start by making your classes - physics, point, line etc. - streamable.

Once you have done that, the rest is easy.
a. read line by line from the file
b. check if the line is a tag for a particular class
c. read in an object of that class from the next line

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
#include <iostream>
#include <string>
#include <sstream>
#include <vector>

struct point
{
    explicit point( int xx = 0, int yy = 0 ) : x(xx), y(yy) {}
    int x ;
    int y ;
};

constexpr char OPENP = '(' ;
constexpr char CLOSEP = ')' ;
constexpr char COMMA = ',' ;

std::ostream& operator<< ( std::ostream& stm, point pt )
{ return stm << OPENP << pt.x << COMMA << pt.y << CLOSEP ; }

std::istream& operator>> ( std::istream& stm, point& pt )
{
    int x, y ;
    char a, b, c ;
    if( stm >> a >> x >> b >> y >> c && a == OPENP && b == COMMA && c == CLOSEP )
    {
        pt = point{ x, y } ;
    }
    else
    {
        pt = point{} ;
        stm.clear( std::ios::failbit ) ;
    }

    return stm ;
}

struct line_segment
{
    line_segment() = default ;
    line_segment( point a, point b ) : from(a), to(b) {}
    line_segment( int x1, int y1, int x2, int y2 ) : from(x1,y1), to(x2,y2) {}

    point from ;
    point to ;
};

std::ostream& operator<< ( std::ostream& stm, const line_segment& line )
{ return stm << line.from << COMMA << ' ' << line.to ; }

std::istream& operator>> ( std::istream& stm, line_segment& line )
{
    point a, b ;
    char c ;
    if( stm >> a >> c >> b && c == COMMA )
    {
        line = line_segment{ a, b } ;
    }
    else
    {
        line = line_segment{} ;
        stm.clear( std::ios::failbit ) ;
    }

    return stm ;
}

int main()
{
    std::istringstream file
    (
        "...\n"
        "other information\n"
        "...\n"
        "physics:\n"
        "4,5,6,7\n"
        "...\n"
        "\n"
        "line:\n"
        "(4,2), (2,4)\n"
        "\n"
        "line:\n"
        "(1,2), (2,3)\n"
        "\n"
        "...\n"
        "line:\n"
        "(6,5), (7,9)\n"
        "...\n"
    );

    const std::string line_tag = "line:" ;
    const std::string physics_tag = "physics:" ;
    std::vector<line_segment> lines ;

    std::string line ;
    while( std::getline( file, line ) ) // for each line in file
    {
        if( line.find(line_tag) == 0 ) // if it is the tag for line
        {
            line_segment line ;
            if( file >> line ) lines.push_back(line) ;
            else file.clear() ;
        }
        else if( line.find(line_tag) == 0 ) // if it is the tag for physics
        {
            // likewise for physics
            // read in, add to collection etc.
        }

        // and likewise for other tags
    }

    for( const auto& ls : lines ) std::cout << ls << '\n' ;
}

http://coliru.stacked-crooked.com/a/bdfa0032636f34cf

If this has to be done at many places, a factory class to instantiate the objects may be be worth considering.
Topic archived. No new replies allowed.