string stream issues

I'm writing a program that uses a while loop to repeatedly create objects with multiple variables within them. To do this, I use a file stream to read lines from a file to a string, then a string stream to pull each individual variable from the string (I don't go straight file to variable because I need to make a copy of the line first for something else). It works great the first iteration, in debugging afterwards I discovered that the string stream was not overwriting the variables from the first iteration. What's going on and how can I fix this so it will overwrite the variables every iteration?
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
while(!ffile.eof())
                {
                    getline(ffile, line);
                    copy = line;

                    ss.str(line);
                    ss >> type;

                    if (type == "Residential")
                    {
                        ss >> rent_or_own >> price >> occupation;
                        getline(ss, address);
                        
                        if (ss.fail() || price < 0)
                        {
                            cout << "Error, ignoring bad input: " << copy << endl << endl;
                            ss.clear();
                            ss.ignore(1000, '/n');
                        }
                        else
                        {
                            Residential* r = new Residential (rent_or_own, price, occupation, address);
                            properties.push_back(r);
                        }
                    }
                    else if (type == "Commercial")
                    {
                        ss >> rent_or_own >> price >> tax_eligibility >> tax_discount;
                        getline(ss, address);

                        if (ss.fail() || price < 0)
                        {
                            cout << "Error, ignoring bad input: " << copy << endl << endl;
                            ss.clear();
                            ss.ignore(1000, '/n');
                        }
                        else
                        {
                            Commercial* c = new Commercial(rent_or_own, price, tax_discount, tax_eligibility, address);
                            properties.push_back(c);
                        }
                    }
                    else
                    {
                        cout << "Error, ignoring bad input: " << copy << endl << endl;
                    } 
                }
There are two issues here, one you didn't ask about. The first is the testing of eof() in the loop condition. This is not good practice - it can lead to several possible problems, such as infinite loops or processing the last line twice. The correct way is to put the file input itself as the loop condition.


The other problem, after the first pass, one or more of the status flags for the stringstream may be set. The flags need to be reset (cleared) before using that stream again.

Change this:
1
2
3
4
5
6
7
8
9
10
11
12
13
    while (!ffile.eof())
    {
        getline(ffile, line);
        copy = line;

        ss.str(line);
        ss >> type;

        if (type == )
        {
 
        } 
    }



to this:
1
2
3
4
5
6
7
8
9
10
11
12
13
    while (getline(ffile, line))   // body of loop is entered only on successful file input
    {
        copy = line;
        
        ss.clear();                // reset status flags for stringstream
        ss.str(line);
        ss >> type;

        if (type == )
        {
 
        } 
    }

Well, there's another possible problem. What if the type cannot be read from the line? You might also check for that:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
    while (getline(ffile, line))   // body of loop is entered only on successful file input
    {
        copy = line;
        
        ss.clear();                // reset status flags for stringstream
        ss.str(line);
        
        if (!(ss >> type))         // proceed only if type can be read
        {
            cout << "Error, type not retrieved, ignoring bad input: " << copy << endl << endl;
            continue;
        }    
        
        if (type == )
        {
     
        }
    }
Topic archived. No new replies allowed.