1

so I was trying to utilise the istringstream to parse through a text file. The idea is to break down each line by space and based on the substring do stuff. The code works fine except for two things, it double counts last substring for each line and it seg faults when its done reading through the file. I have not used sstream before so any insight would be helpful.

file.getline(str,80);

    while(!file.eof())

    {

        cout<<str<<endl;
        istringstream iss(str);
        while (iss)
            {
                iss >> sstr;
                cout << "Substring: " <<sstr << endl;
         }
        file.getline(str,80);   
    }
noob
  • 93
  • 1
  • 6
  • I would highly encourage changing from `file.getline(str, 80);` to `std::getline(file, str);` ( http://www.cplusplus.com/reference/string/getline/ ), assuming `str` is a `std::string`. At the very least, you don't have to worry about lines that are "too long." – Max Lybbert Sep 08 '11 at 17:37
  • Thanks a ton guys....works like a charm. I used the getline as the first while loop condition and iss>>sstr as the second while loop condition. – noob Sep 08 '11 at 17:52
  • 1
    I would also highly encourage changing from `while(!file.eof())` to `while(file)` which will also stop on stream errors. – Mooing Duck Sep 08 '11 at 17:53

2 Answers2

5

The while loops should go like this:

std::string line;

while (std::getline(file, line))
{
    std::istringstream iss(line);
    std::string token;

    while (iss >> token)
    {
        cout << "Substring: " << token << endl;
    }
}

The getline and input operations return the stream object, which itself has a specialized conversion to bool that indicates whether the operation succeeded, and it will fail precisely when you've reached the end of the respective stream.

Kerrek SB
  • 464,522
  • 92
  • 875
  • 1,084
2

while !eof is almost always wrong.

Switch to a different C++ book, and tell us which one you're using now so that we may mock and warn accordingly.

while (file.getline(str,80)) {
    cout<<str<<endl;
    istringstream iss(str);
    while (iss >> sstr) {
       cout << "Substring: " <<sstr << endl;
    }
}
Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055
  • Hm, the member-`getline` is a bit clunky for my taste... as is the magic `80`. – Kerrek SB Sep 08 '11 at 17:51
  • @Kerrek: Indeed, global `getline` would be better. But I'm just fixing _one_ error here. :) – Lightness Races in Orbit Sep 08 '11 at 17:52
  • I have seen !eof() in a ton of books. Could you point me to as to why its a bd idea? nvm found it...thanks!! – noob Sep 08 '11 at 17:53
  • @Tomalak: Yeah, usually one error at a time is the Right Way. But this time I tried to measure carefully what the OP wanted and what I thought he needed and took a shot... it's thin ice, though -- other times that sort of liberty gets you downvoted :-) – Kerrek SB Sep 08 '11 at 18:21