ostream

Hi guys I know why I am getting an error but I don't know how to solve it

I'm reading from a file called books.txt which contains the following data

1:adam:IT:2:Steve:IT:3:Bill:IT:

what I want to happen is when I reach the last entry in this case Bill I want to discard the : and get to the end of the file,the problem is I get stuck in an infinite loop because it never reaches the end of the file it will always have a left over : thus the loop will never terminate

I tried using in.get() but that didn't work at all and it probably won't solve the problem because it would eat the delimiter which I need in the cases that are not the end case.

thanks

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
  vector<info> names;
    int id;
    string name,department;
    int choice;
    ofstream out;
    ifstream in;
    stringstream ss;
    int a;
    string b,c;
    string d;
    string discard;
    

    while(!in.eof()){

    cout << "hi" << endl;
    in.open("books.txt");
    getline(in,d,':');
    ss << d;
    ss >> a;
    getline(in,b,':');
    getline(in,c,':');
    getline(in,discard,':');
    


    info temp(a,b,c);

    names.push_back(temp);

    }



**edit I sort have fixed the infinite loop problem but now I have run into another problem when I try to populate the vector with the data in my books.txt file only adam seems to get added and the rest seem to be discarded for some reason

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
 while(!in.eof()){

    cout << "hi" << endl;
    in.open("books.txt");
    getline(in,d,':');
    ss << d;
    ss >> a;
    ss.clear();
    ss.str(string());

    getline(in,b,':');
    getline(in,c,':');

    if(!in){
        break;
    }

    info temp(a,b,c);
    names.push_back(temp);

    }

Last edited on
silly me I should have opened in before the while loop,now everything works fine but question why did adam only get added to the names vector when in.open() was placed in the while loop?

and I thought it would have got stuck in an infinite loop since we would be constantly opening the file?

thanks
Regardless of perhaps getting it to work sometimes, it is not a good idea to use eof() as the loop condition. A better approach is to put the input operation itself as the loop condition.

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
#include <iostream>
#include <iomanip>
#include <string>
#include <vector>
#include <fstream>

using namespace std;

struct info {
    int id;
    string name;
    string department;
};

int main()
{
    vector<info> names;
    
    ifstream in("books.txt");    
    if (!in)
    {
        cout << "Input file is not open\n";
        return 1;
    }

    info temp;
    char dummy;
    
    while (in >> temp.id >> dummy &&
           getline(in, temp.name, ':') &&
           getline(in, temp.department, ':') )
    {
        names.push_back(temp);
    }
    
    
    // Now print it out
    for (auto & a : names)
        cout << setw(10) << a.id 
             << setw(20) << a.name 
             << setw(20) << a.department
             << '\n';
}


In practice I would probably write a self-contained function to input a single object, and put that as the loop condition. Or overload the input operator >> for info. Then the loop would be simply
1
2
    while (in >> temp)
        names.push_back(temp);



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
#include <iostream>
#include <iomanip>
#include <string>
#include <vector>
#include <fstream>

using namespace std;

class info {
    int id;
    string name;
    string department;
    
public:
    friend istream & operator >> (istream & is, info & i)
    {
        char dummy;
        is >> i.id >> dummy;
        getline(is, i.name, ':');
        getline(is, i.department, ':');
        return is;
    }
    
    friend ostream & operator << (ostream & os, const info & i)
    {
        os << setw(10) << i.id 
           << setw(20) << i.name 
           << setw(20) << i.department;
        return os;
    }
    
};

int main()
{
    vector<info> names;
    
    ifstream in("books.txt");    
    if (!in)
    {
        cout << "Input file is not open\n";
        return 1;
    }

    info temp;
    
    while (in >> temp)
        names.push_back(temp);
    
    // Now print it out
    for (auto & a : names)
        cout << a << '\n';
}

Last edited on
now everything works fine but question why did adam only get added to the names vector when in.open() was placed in the while loop?

You can only open the file once (unless you subsequently close it first). As it stands, after the second open attempt, the file status will be 'fail' (failed to open an already open file) and so the break statement is executed:
14
15
16
    if(!in){
        break;
    }
thanks Chervil
Registered users can post here. Sign in or register to post.