Этот код зацикливается навсегда:
#include <iostream>
#include <fstream>
#include <sstream>
int main(int argc, char *argv[])
{
std::ifstream f(argv[1]);
std::ostringstream ostr;
while(f && !f.eof())
{
char b[5000];
std::size_t read = f.readsome(b, sizeof b);
std::cerr << "Read: " << read << " bytes" << std::endl;
ostr.write(b, read);
}
}
Это потому, что readsome
никогда не устанавливает eofbit
.
cplusplus.com говорит:
Ошибки сообщаются путем изменения внутренних флагов состояния:
eofbit
При вызове функции указатель get находится в конце внутреннего входного массива буфера потока, что означает отсутствие позиций.быть прочитанным во внутреннем буфере (который может быть или не быть концом входной последовательности).Это происходит, когда rdbuf()->in_avail()
вернет -1
до извлечения первого символа.
failbit
Поток находился в конце источника символов до вызова функции.
badbit
Произошла ошибка, отличная от описанной выше.
Почти то же самое, стандарт гласит:
[C++11: 27.7.2.3]:
streamsize readsome(char_type* s, streamsize n);
32.Эффекты: ведет себя как неотформатированная функция ввода (как описано в пункте 27.7.2.3, параграф 1).После создания объекта-часового, если !good()
вызывает setstate(failbit)
, который может вызвать исключение и вернуться.В противном случае извлекает символы и сохраняет их в последовательных местах массива, первый элемент которого обозначен s
.Если rdbuf()->in_avail() == -1
, вызывает setstate(eofbit)
(что может выдать ios_base::failure
(27.5.5.4)) и не извлекает никаких символов;
- Если
rdbuf()->in_avail() == 0
, не извлекает никаких символов - Если
rdbuf()->in_avail() > 0
, извлекается min(rdbuf()->in_avail(),n))
.
33.Возвращает: Количество извлеченных символов.
То, что условие in_avail() == 0
является неактивным, подразумевает, что ifstream::readsome
само по себе является недопустимым, если буфер потока пуст, ноусловие in_avail() == -1
подразумевает, что оно будет устанавливать eofbit
, когда какая-то другая операция привела к in_avail() == -1
.
Это выглядит как несоответствие, даже несмотря на то, что«некоторая» природа readsome
.
Так что же является семантикой readsome
и eof
?Правильно ли я их истолковал?Являются ли они примером плохого дизайна в библиотеке потоков?
(Украдено из [IMO] недействительно libstdc ++ ошибка 52169 .)