Разделение строки на целые числа с использованием istringstream в С++
Я пытаюсь использовать istringstream
для разделения простой строки на ряд целых чисел:
#include <string>
#include <iostream>
#include <sstream>
#include <vector>
using namespace std;
int main(){
string s = "1 2 3";
istringstream iss(s);
while (iss)
{
int n;
iss >> n;
cout << "* " << n << endl;
}
}
И я получаю:
* 1
* 2
* 3
* 3
Почему последний элемент всегда выходит дважды? Как это исправить?
Ответы
Ответ 1
Это выходит дважды, потому что ваш цикл неправильный, как объяснено (косвенно) на http://www.parashift.com/c++-faq-lite/input-output.html#faq-15.5 (while (iss)
не отличается от while (iss.eof())
в этом сценарии).
В частности, на третьей итерации цикла iss >> n
преуспевает и получает ваш 3
и оставляет поток в хорошем состоянии. Этот цикл затем выполняется в четвертый раз из-за этого хорошего состояния, и это происходит только тогда, когда следующий (четвертый) iss >> n
впоследствии не завершится, так как условие цикла нарушено. Но до окончания этой четвертой итерации вы все равно выводите n
... в четвертый раз.
Try:
#include <string>
#include <iostream>
#include <sstream>
#include <vector>
using namespace std;
int main()
{
string s = "1 2 3";
istringstream iss(s);
int n;
while (iss >> n) {
cout << "* " << n << endl;
}
}
Ответ 2
Надеюсь, что это поможет:
iss: 1 2 3
Итерация 1
iss: 1 2 3 (изначально)
п = 1
iss: 2 3
// * 1 печатается
Итерация 2:
iss: 2 3 (изначально)
п = 2
iss: 3
// * 2 печатается
Итерация 3
iss: 3
п = 3
iss: ''
Итерация 4
iss: ''
n не изменено//Набор флагов для eof of iss как никакой дополнительный вход из потока
iss: ''
И как справедливо упомянуто выше, в то время как (iss) не отличается от while (iss.eof()).
Внутри функция (istream:: operator → ) обращается к входной последовательности, сначала создавая объект sentry (с noskipws, установленным на false [ Это означает, что пространство является разделителем, а ваш список будет 1,2,3]). Затем (если good [здесь не достигнуто]), он вызывает num_get:: get [Получить следующее целое число] для выполнения операций извлечения и синтаксического анализа, соответственно, соответствующим образом изменяя флаги состояния потока. Наконец, перед тем, как вернуться, он разрушает объект часовой.
Обратитесь: http://www.cplusplus.com/reference/istream/istream/operator%3E%3E/