Чтение из входных потоков

У меня есть задание по программированию для курса C ++, включающего потоки, и я пытаюсь лучше понять, почему некоторые функции работают так, как они работают.

Я читаю ввод из istringstream с пробелами после текста. Почему последнее слово повторяется в выводе?

istringstream is;
string inputstring = "The cliched statement regarding the big brown dog and foobar or something    ";
string outputstring;
is.str(inputstring);
while (is.good())
{
is >> outputstring;
cout << outputstring << endl;
}

Итак, вместо того, чтобы зацикливаться на хорошем флаге, я сейчас выполняю извлечение как условие while:

while (is >> outputstring)
...

Это хорошо работает и не повторяет последнее слово. Что такого в этом утверждении, которое выходит из цикла while, когда оно завершает чтение? Извлечение возвращает ссылку на тот же поток, но он проверяет флаги или что-то?

Есть ли один заголовок, который позволяет включать все потоки?

1

Решение

Что такого в этом утверждении, которое выходит из цикла while, когда оно завершает чтение? Извлечение возвращает ссылку на тот же поток, но он проверяет флаги или что-то?

Вы абсолютно правы в том, что оператор извлечения возвращает ссылку на поток. Любое выражение, используемое в качестве условия управления while петля (также for а также dowhile петля и if заявление) принуждается к bool тип. Это считается explicit преобразование, так ios_base::operator bool() называется, который возвращает !this->fail(), И вот как флаги проверяются.

2

Другие решения

Почему последнее слово повторяется в выводе?

Вот что происходит: потому что у вас есть пробелы в конце inputstringчтение последнего слова не переворачивает бит good (). Программа находит пробел после последнего слова, думает, что есть больше слов, поэтому is.good() все еще возвращается true, is.good() возвращает ложь только в том случае, если программа пыталась прочитать после конца строки; этого еще не произошло.

Затем в следующий раз, когда вы пройдете через цикл и прочитаете is, программа понимает, что больше нет слов, не переписывает outputstringи так вы еще раз напишите, что было в outputstring до того, что последнее слово.

попробуйте распечатать результат is.good() до и после прочтения isи удалите пробелы в конце inputstring чтобы увидеть, что меняется …

1

Вы всегда должны проверить после чтение, потому что поток может быть в хорошем состоянии, но попытка что-то прочитать может дать сбой: в конце концов, поток не может знать, что вы собираетесь прочитать. Таким образом, когда вы проверяете поток после последнего элемента, он все еще good(), Затем вы пытаетесь прочитать, что не удается и good() является false но вы все равно печатаете значение.

Вас также не хочу использовать .good() в качестве условия, поскольку это может повернуться к false даже после успешного чтения, если достигнут конец потока. Например, если число прочитано и после номера в конце файла нет пробелов, то std::ios_base::eofbit установлено. Просто используйте idomatic цикл как это:

while (in >> value) {
std::cout << "read value='" << value << "'\n";
}

Это выглядит слишком просто, чтобы быть правильным, но на самом деле делает правильно!

0
По вопросам рекламы [email protected]