Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Problem extracting formatted input from an istringstream that has been set twice

Thanks for the help.
My program reads lines from stdin. The first one has a single number which determines the mode at which the program is running, and the rest contain sequences of numbers of undetermined length. The number of lines is determined by the mode. I want to parse those lines into vectors of int. To do this, I am using getline and istringstream. I then get the numbers with formatted extraction >>. The first time I pass the string to the stream, there isn’t any problem, the string is correctly passed to the stream, and I can read formatted input from it. However, if I get another line and pass it to the same stream, then something weird happens. The string is correctly copied to the stream, which I confer by writing

std::cout << iss.str() << std::endl

However, when I try to extract the numbers from the line, it doesn’t.

Here is a Minimum Reproducible Example:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

(I have tried to do it with two different streams and it works, the problem is that I have the cases inside a switch block, so it doesn’t let me initialize streams inside it, and the number of streams changes quite a bit from mode to mode.)

#include <iostream>
#include <sstream>
#include <vector>
#include <string>

using namespace std;

int main()
{
    string line;
    int problem_type = -1, input_number = -1;
    vector<int> sequence;
    istringstream iss;

    /* Get the problem type */
    getline(cin, line);
    iss.str(line);
    if (!iss)
        return -1;
    cout << "Stream contents: " << iss.str() << endl;
    iss >> problem_type;
    cout << "Extracted numbers: " << problem_type << endl;
    
    getline(cin, line);
    iss.str(line);
    if (!iss)
        return -1;
    cout << "Stream contents: " << iss.str() << endl;

    cout << "Extracted numbers:";
    while(iss >> input_number) {
        cout << " " << input_number;
        sequence.push_back(input_number);
    }
    cout << endl;
    return 0;
}

Input:

1
1 2 3 4 5

Output:

Stream contents: 2
Extracted numbers: 2
Stream contents: 1 2 3 4 5
Extracted numbers:

Expected Output:

Stream contents: 2
Extracted numbers: 2
Stream contents: 1 2 3 4 5
Extracted numbers: 1 2 3 4 5

>Solution :

Once you read iss >> problem_type;,

cout << "eof: " << iss.eof() << endl;

outputs

eof: 1

The next iss.str(line); does not reset the stream state, the loop condition is false. You want

iss.clear();
while(iss >> input_number) {
    cout << " " << input_number;
    sequence.push_back(input_number);
}

Output

Stream contents: 1
Extracted numbers: 1
Stream contents: 1 2 3 4 5
Extracted numbers: 1 2 3 4 5
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading