быдлокодер
1722 / 909 / 106
Регистрация: 04.06.2008
Сообщений: 5,655
|
|||||||||||
1 | |||||||||||
Почему если флаг состояния потока eof поднят, то флаг good опущен?19.10.2014, 21:28. Показов 2464. Ответов 15
Метки нет Все метки)
(
Почему если флаг состояния потока eof поднят, то флаг good опущен?
Это нонсенс, друзья. Здесь прочтём, что флаг goodbit потока поднят, если опущены все флаги eofbit, failbit and badbit И тут же пониже, что флаг eof поднят, когда достигнут конец входного потока, то есть по-русски говоря, когда всё считалось OK А вот код, подтверждающий это. Задействованы все флаги на всякий случай, чтобы было видно, что goodbit опущен только из-за одно поднятого eofbit
0
|
|
19.10.2014, 21:28 | |
Ответы с готовыми решениями:
15
Флаг failbit для перенаправления строкового потока; почему он всегда у меня поднят?
Получить флаг о готовности данных от дочернего потока Олимпийский флаг, почему не рисуется? |
7361 / 6284 / 2855
Регистрация: 14.04.2014
Сообщений: 27,223
|
|
19.10.2014, 21:34 | 2 |
Потому что читать больше нечего из потока.
0
|
быдлокодер
1722 / 909 / 106
Регистрация: 04.06.2008
Сообщений: 5,655
|
|
19.10.2014, 21:38 [ТС] | 3 |
И поэтому я должен думать, что прочитано плохо или неправильно или вообще не прочитано?
0
|
7361 / 6284 / 2855
Регистрация: 14.04.2014
Сообщений: 27,223
|
|
19.10.2014, 21:43 | 4 |
Для этого есть отдельные три флага. good - это для того, чтобы начинать или не начинать новую операцию, а не для анализа старой.
1
|
Вездепух
![]() ![]() 10820 / 5841 / 1585
Регистрация: 18.10.2014
Сообщений: 14,496
|
|||||||||||
20.10.2014, 08:05 | 5 | ||||||||||
В стандартных потоках флаг конца файла поднимается не тогда, когда указатель чтения просто тихонько "достиг конца файла", а тогда, когда вызывающий код предпримет попытку продвинуть его дальше, за конец файла. То есть флаг конца файла будет поднят тогда, когда конец файла фактически уже достигнут, а внешний код (который об этом еще не знает) тем не менее попытается выполнить попытку чтения данных из файла. Эта попытка будет, разумеется, неудачной. И вот только в этот момент в потоке будет поднят флаг 'eof'.
Таким образом, поднятие флага 'eof' - это всегда результат ошибочной ситуации - попытки чтения несуществующих данных за концом файла. Именно по этой причине ситуация 'eof' не считается 'good'. Вот в таком коде, где входной поток состоит из одного единственного символа, флаг 'eof' после прочтения этого символа выставлен не будет. А появится он только после попытки прочтения второго, несуществующего символа.
Например, в вашем примере вы читаете из потока строку неограниченной длины. Алгоритм чтения строки будет выдергивать из входного потока один символ за другим, пока не встретит пробел или конец файла. "Встретит конец файла" в данном случае означает именно "попытается прочитать несуществующий символ". Именно это и происходит в вашем примере. Оператор 'is >> str' успешно читает шесть символов (флага 'eof' после этого еще не возникает), а затем пытается прочитать седьмой. Это ему не удается и выставляется флаг 'eof'. Именно этот флаг вы и видите в вызывающем коде. Однако если вы будете читать вашу строку вот так
0
|
:)
![]() 4773 / 3267 / 497
Регистрация: 19.02.2013
Сообщений: 9,046
|
|
20.10.2014, 10:43 | 6 |
В gcc это не так:
http://coliru.stacked-crooked.... 2640cb899a А вот в студии eof действительно не выставляется.
0
|
Вездепух
![]() ![]() 10820 / 5841 / 1585
Регистрация: 18.10.2014
Сообщений: 14,496
|
|
20.10.2014, 11:14 | 7 |
Это интересная деталь. Это, по-видимому, означает, что условие завершения чтения в gcc первым делом проверяет входной поток на пробельный символ и лишь потом проверяет ограничение на длину. Попытка проверки на пробельный символ (т.е. попытка чтения следующего символа) и выставляет eof.
Интересно, специфицирует ли стандарт языка порядок проверки условий завершения чтения.
0
|
27 / 27 / 18
Регистрация: 13.09.2014
Сообщений: 137
|
||||||
20.10.2014, 11:39 | 8 | |||||
А если через строку, то
Это просто так реализовано? (думаю из-за '\0' в конце)
0
|
7361 / 6284 / 2855
Регистрация: 14.04.2014
Сообщений: 27,223
|
|
20.10.2014, 11:55 | 9 |
Разве setw() применим для ввода?
0
|
306 / 101 / 18
Регистрация: 04.07.2014
Сообщений: 571
|
|
20.10.2014, 12:22 | 11 |
Tulosba, всё же, eof устанавливается только при попытке чтения за пределы конца потока, то есть должна быть ошибка чтения. А вот как там действует setw на input stream -- это вопрос. Например, если Вы будете читать в char*, то поведение будет false.
На StackOverflow, по-моему, писали, что setw читает на один символ больше, ожидая нулевого символа завершения строки. Как-то так. Но я не могу быть уверен.
0
|
:)
![]() 4773 / 3267 / 497
Регистрация: 19.02.2013
Сообщений: 9,046
|
|||||||||||
20.10.2014, 13:03 | 12 | ||||||||||
Порылся немного в исходниках. Как я понял, прикол с eof возникает из-за различий в реализации цикла чтения из потока. В студии (VS2010) он такой:
В gcc же имеем такой код (источник):
Поэтому как раз наблюдаем ситуацию: прочитали нормально n символов, но внутри считался ещё 1 дополнительно перед выходом из цикла. И после выхода как раз выставился eof (чего в варианте VS не происходит). Стандарт же на этот счет говорит всего лишь следующее 21.4.8.9: Но вот можно ли при этом утверждать что gcc не соответствует Стандарту, я не особо уверен.
1
|
4203 / 1795 / 211
Регистрация: 24.11.2009
Сообщений: 27,562
|
|
20.10.2014, 13:15 | 13 |
Ты просто не понимаешь национальную логику авторов, а флаг good сбрасывается потому, что дальше читать без гоги уже нельзя.
0
|
:)
![]() 4773 / 3267 / 497
Регистрация: 19.02.2013
Сообщений: 9,046
|
||||||
20.10.2014, 13:51 | 14 | |||||
В gcc ещё, как оказалось, с символьным массивом будет поведение, отличное от std::string.
Т.е. такой код:
вернет eof() == true для std::string, но ==false для char[]. Хотя, казалось бы, поведение должно быть согласовано.
0
|
Вездепух
![]() ![]() 10820 / 5841 / 1585
Регистрация: 18.10.2014
Сообщений: 14,496
|
|
20.10.2014, 18:08 | 15 |
Не совсем понимаю примера. У меня вышепроцитированным примером кода читается и выводится именно 6 символов, и в gcс, и в MSVC.
Если читать в массив 'char', то читаться действительно будет только 5 символов, т.е. на один меньше, чем указано в 'setw'. Но так и должно быть - стандарт это явно оговаривает. А если читать в 'std::string', то читаться будет 6 символов. Добавлено через 2 минуты Это как раз таки явно оговорено в стандарте. Для 'char []' читается 'n - 1' символ, а для 'string' - 'n' символов (где 'n' - величина, заданная в 'setw').
0
|
:)
![]() 4773 / 3267 / 497
Регистрация: 19.02.2013
Сообщений: 9,046
|
|
20.10.2014, 18:57 | 16 |
Ну тогда действительно поведение eof в gcc остается согласованным между char[] и std::string.
Но вот вопрос об установке самого значения eof пока не очень ![]()
0
|
20.10.2014, 18:57 | |
Помогаю со студенческими работами здесь
16
Сколькими способами можно сшить трехцветный флаг, если есть ткани 5 различных цветов?
Почему событие eof() файлового потока наступает очень поздно? Какова вообще его логика? Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |