Как читать поток строк с динамическим размером? - PullRequest
9 голосов
/ 21 сентября 2010

Я хотел поэкспериментировать с stringstream для задания, но я немного запутался, как это работает.Я сделал быстрый поиск, но не смог найти ничего, что ответило бы на мой вопрос.

Скажем, у меня есть поток с динамическим размером, как я узнаю, когда прекратить запись в переменную?

 string var = "2 ++ asdf 3 * c";
 stringstream ss;

 ss << var;

 while(ss){
  ss >> var;
  cout << var << endl;
 }

и мой вывод будет:

2  
++  
asdf  
3  
*  
c  
c  

Я не уверен, почему я получаю этот дополнительный 'c' в конце, особенно потому что _M_in_cur = 0x1001000d7 ""

Ответы [ 3 ]

20 голосов
/ 21 сентября 2010

Вы получаете дополнительные c в конце, потому что вы не проверяете, хорош ли поток после выполнения извлечения:

while (ss)        // test if stream is good
{
    ss >> var;    // attempt extraction          <-- the stream state is set here
    cout << var;  // use result of extraction
}

Вам необходимо проверить состояние потока между тем, когда вы выполняете извлечение и когда вы используете результат. Обычно это делается путем выполнения извлечения в цикле:

while (ss >> var) // attempt extraction then test if stream is good
{
    cout << var;  // use result of extraction
}
0 голосов
/ 22 сентября 2010

Проверка состояния while(ss) в вашем коде проверяет, было ли последнее чтение из потока успешным или нет.Однако эта проверка вернет true, даже если вы прочитали последнее слово в вашей строке.Только следующее извлечение ss >> var в вашем коде сделает это условие ложным, так как достигнут конец потока и нечего извлекать в переменную var.Это причина, по которой вы получаете дополнительный «с» в конце.Вы можете устранить это, изменив код в соответствии с предложением Джеймса Макнеллиса.

0 голосов
/ 21 сентября 2010

Существует также функция-член good (), которая проверяет, может ли поток использоваться для операций ввода-вывода.Таким образом, используя приведенный выше код можно изменить на

while(ss.good())  // check if the stream can be used for io
{
    ss >> var;    // attempt extraction          <-- the stream state is set here
    cout << var;  // use result of extraction
}
...