Проблема с повторным использованием объекта stringstream - PullRequest
9 голосов
/ 27 января 2010

Я пытаюсь использовать безопасные методы обработки ввода с числами только в 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 так, как я пытаюсь это сделать? В моей настоящей программе я собираюсь обработать намного больше двух входных значений от пользователя, поэтому я просто хочу убедиться, что есть другой способ, вместо создания нескольких объектов stringstream. Я сомневаюсь, что это очень важно, но я использую Windows XP и использую MinGW в качестве компилятора.

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

Ответы [ 4 ]

13 голосов
/ 27 января 2010

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

11 голосов
/ 27 января 2010

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

sstream.str("");

и сброс флажков состояния ошибки:

sstream.clear();

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

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

4 голосов
/ 27 января 2010

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

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

Ниже приведен пример преобразования int в строку и обратно (строка в 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;
}
2 голосов
/ 27 января 2010
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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...