开发者

Problem with re-using a stringstream object

I'm trying to use safe practices in handling input with numbers only in C开发者_JS百科++, so I use a stringstream object as so:

#include <iostream>
#include <string>
#include <sstream>
using namespace std;

int main()
{
    int first, second;
    string input;

    stringstream sstream;

    cout << "First integer: ";
    getline(cin, input);
    sstream.str(input);
    sstream >> first;

    cout << first << endl; //display user input in integers

    cout << "Second integer: ";
    getline(cin, input);
    sstream.str(input);
    sstream >> second;

    cout << second << endl; //display user input in integers

    getline(cin, input); //pause program

    return 0;
}

However, the second time around it seems to give the variable 'second' an arbitrary value. This is the output:

First integer: 1
1
Second integer: 2
2293592

If I declare two stringstream objects and use them respectively for both variables it seems to work fine. Does this mean that I cannot re-use a stringstream object in the way I'm trying to do? In my real program I intend to handle much more than two input values from the user, so I just want to make sure if there's another way instead of making multiple stringstream objects. I doubt it's of great relevance but I'm on Windows XP and I'm using MinGW as my compiler.

I greatly appreciate any help.


Use sstream.clear(); after sstream >> first;.


You need to reset the state of the stringstream. Generally, this involves two steps: clearing the buffer:

sstream.str("");

and resetting the error state flags:

sstream.clear();

If you don't clear the buffer, if you get an input like "123abc" then "abc" will still be in the stream when you try to read from it the next time.

You should also make sure to test the fail state of the stream (sstream.fail()) to ensure that the extraction was successful. If you want to be sure that the user only entered an integer (i.e., you want to prevent the user from inputting, say, "123abc", then you should test to make sure sstream.eof() is true.


A better way to do this conversion between datatypes would be to use boost::lexical_cast.

Info and examples can be found at the Boost Site.

Below is an example of doing an int to string conversion and back (string to int) such as what you're doing in your program.

#include <string>
#include <boost/lexcal_cast.hpp>

int main(int argc, char *argv[])
{
    int i = 42;
    std::string s = boost::lexical_cast<std::string>(i);
    int j = boost::lexical_cast<int>(s);

    return 1;
}


cout << "First integer: ";
getline(cin, input);
sstream.str(input);
sstream >> first;     // state of sstream may be eof

cout << "Second integer: ";
getline(cin, input);
sstream.str(input);
sstream.clear();      // clear eof state
sstream >> second;    // input from sstream
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜