Stringstreams

Greetings. Here is my input file...

1
2
3
4
5
6
apples bananas dates
bananas cherries figs
cherries apples eggs
dates eggs figs
eggs apples bananas
figs apples dates


my goal is to write a program using stringstreams to print this file out. My first attempt works perfectly using the following code.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <iostream>
#include <fstream>
#include <sstream>

using namespace std;

int main()
{
    ifstream ifs{"data.txt"};
    istringstream ss;
    string line;

    while( getline(ifs, line) )
    {
        ss.str( line );
        cout << ss.str() << "\n";
    }

    return 0;
}


My next version is slightly more complicated. I want to read the words from each line one word at a time. Here is the code for this second version...

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <iostream>
#include <fstream>
#include <sstream>

using namespace std;

int main()
{
    ifstream ifs("data.txt");
    istringstream ss;
    string line, word;

    while( getline(ifs, line) )
    {
        ss.str( line );
        while( ss >> word )
            cout << word << " ";

        cout << "\n";
    }
}


The problem is that only the first line of the file gets printed. From the appearance of my console window, it looks like blank lines are being printed for the remaining lines of the file. I can't figure out why. If anyone can clue me in I would be most grateful.
Last edited on
the loop in line 16 makes the stringstream invalid, so when reading the next line the extraction fails.

You may ss.clear(); ss.str( line );
Or construct the stream inside the loop on line 13
1
2
while( getline(ifs, line) ){
   istringstream ss(line);
Last edited on
Thanks. I found a tutorial which seems to imply that the string stream must be cleared, or created anew, before it is re-used. This is consistent with your solutions, both of which work. Could it be that the stringstream goes into an eof() state after processing the first line, and this needs to be reset explicitly.

http://www.learncpp.com/cpp-tutorial/134-stream-classes-for-strings/
Last edited on
When re-using any stream you always need to be concerned about the prior error state, so before you re-use the stream it is best to clear any errors. And don't forget eof() is only one of the errors that may be set on a stream.

I'm still missing something. Here is the solution to my original problem. Adding an ss.clear() did the trick;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <iostream>
#include <fstream>
#include <sstream>

using namespace std;

int main()
{
    ifstream ifs("data.txt");
    istringstream ss;
    string line, word;

    while( getline(ifs, line) )
    {
        ss.clear();
        ss.str( line );
        while( ss >> word )
        {
            cout << word << " ";
        }
        cout << "\n";
    }
}


but as soon as a elaborate on the code inside the inner while loop, things go awry. for example, I want to only print out the lines that contain a certain word...
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
#include <iostream>
#include <fstream>
#include <sstream>

using namespace std;

int main()
{
    ifstream ifs("data.txt");
    istringstream ss;
    string line, word;
    string search_str = "apple";

    while( getline(ifs, line) )
    {
        ss.clear();
        ss.str( line );
        while( ss >> word )
        {
            if( word == search_str )
            {
                cout << ss.str() << "\n";
                break;
            }
        }
    }
}


nothing gets printed.
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 <fstream>
#include <sstream>

int main()
{
    const char* const path = "data.txt" ;

    {
        std::ofstream(path) <<  "apples bananas dates\n"
                                "bananas cherries figs\n"
                                "cherries apples eggs\n"
                                "dates eggs figs\n"
                                "eggs apples bananas\n"
                                "figs apples dates\n" ;
    }

    std::ifstream file(path);
    const std::string search_str = "apples"; // *** apples ***

    std::string line ;
    while( getline( file, line ) )
    {
        std::istringstream stm(line) ;
        std::string word ;
        while( stm >> word )
        {
            if( word == search_str )
            {
                std::cout << stm.str() << '\n' ;
                break ;
            }
        }
    }
}

http://coliru.stacked-crooked.com/a/cd1deda054cbc067
doh!!!

In my latest failed attempt I used the search string "apple" when I should have used "apples". Nothing printed because the program could not find the word "apple". In other words the code was working fine.
Topic archived. No new replies allowed.