Stringstreams

Jul 30, 2015 at 2:50am
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 Jul 30, 2015 at 3:00am
Jul 30, 2015 at 4:25am
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 Jul 30, 2015 at 4:26am
Jul 30, 2015 at 3:43pm
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 Jul 30, 2015 at 3:44pm
Jul 30, 2015 at 3:57pm
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.

Jul 30, 2015 at 5:08pm
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 Jul 30, 2015 at 5:23pm
Jul 30, 2015 at 5:41pm
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
Jul 30, 2015 at 6:23pm
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.