Проблема с повторным использованием объекта stringstream

Я пытаюсь использовать безопасные методы при обработке ввода с числами только в C++, поэтому я использую объект stringstream следующим образом:

#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;
}

Тем не менее, второй раз кажется, что переменная 'second' имеет произвольное значение. Это вывод:

First integer: 1
1
Second integer: 2
2293592

Если я объявляю два объекта stringstream и использую их соответственно для обеих переменных, то это, кажется, работает нормально. Означает ли это, что я не могу повторно использовать объект stringstream так, как я пытаюсь это сделать? В моей настоящей программе я собираюсь обработать намного больше двух входных значений от пользователя, поэтому я просто хочу убедиться, что есть другой способ, вместо создания нескольких строковых объектов. Я сомневаюсь, что это очень важно, но я использую Windows XP и использую MinGW в качестве компилятора.

Я очень ценю любую помощь.

4 ответа

Решение

Использование sstream.clear(); после sstream >> first;,

Вам нужно сбросить состояние stringstream, Обычно это включает два этапа: очистка буфера:

sstream.str("");

и сбросить флаги состояния ошибки:

sstream.clear();

Если вы не очистите буфер, если вы получите ввод типа "123abc", тогда "abc" все равно будет в потоке, когда вы попытаетесь прочитать его в следующий раз.

Вы также должны проверить состояние сбоя потока (sstream.fail()) чтобы добыча прошла успешно. Если вы хотите быть уверены, что пользователь ввел только целое число (т. Е. Вы хотите запретить пользователю вводить, скажем, "123abc"), вам следует проверить, чтобы убедиться, что sstream.eof() правда.

Лучший способ сделать это преобразование между типами данных было бы использовать boost::lexical_cast,

Информацию и примеры можно найти на сайте Boost.

Ниже приведен пример преобразования int в строку и обратно (string to int), например, то, что вы делаете в своей программе.

#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
Другие вопросы по тегам