istreambuf_iterator
От: GregZ СССР  
Дата: 06.10.05 11:02
Оценка:
Как используя istreambuf_iterator понять, что при чтении произошла ошибка?

  std::copy(std::istream_iterator<char>(istr), std::istream_iterator<char>(), std::back_inserter(buf));
  // данные прочитались успешно?
Re: istreambuf_iterator
От: Аноним  
Дата: 06.10.05 11:07
Оценка:
Здравствуйте, GregZ, Вы писали:

GZ>Как используя istreambuf_iterator понять, что при чтении произошла ошибка?


GZ>
GZ>  std::copy(std::istream_iterator<char>(istr), std::istream_iterator<char>(), std::back_inserter(buf));
GZ>  // данные прочитались успешно?
GZ>


В случае ошибки — исключение.
Re: istreambuf_iterator
От: GregZ СССР  
Дата: 06.10.05 11:15
Оценка:
Здравствуйте, GregZ, Вы писали:

GZ>Как используя istreambuf_iterator понять, что при чтении произошла ошибка?


GZ>
GZ>  std::copy(std::istreambuf_iterator<char>(istr), std::istreambuf_iterator<char>(), std::back_inserter(buf));
GZ>  // данные прочитались успешно?
GZ>


Извиняюсь — в пример конечно же должен быть istreambuf_iterator
Re[2]: istreambuf_iterator
От: GregZ СССР  
Дата: 06.10.05 11:20
Оценка:
Здравствуйте, Аноним, Вы писали:

GZ>>Как используя istreambuf_iterator понять, что при чтении произошла ошибка?


GZ>>
GZ>>  std::copy(std::istream_iterator<char>(istr), std::istream_iterator<char>(), std::back_inserter(buf));
GZ>>  // данные прочитались успешно?
GZ>>


А>В случае ошибки — исключение.


Я ошибся — в примере должен быть istreambuf_iterator.
Для istream_iterator все понятно. Проверять флаги eof, bad, fail я умею. Как и ловить соответствующие им исключения, для чего предварительно необходимо вызвать exception.

Меня интересует другое — как быть с istreambuf_iterator?
Re: istreambuf_iterator
От: Анатолий Широков СССР  
Дата: 06.10.05 11:23
Оценка:
std::copy(std::istream_iterator<char>(istr), std::istream_iterator<char>(), std::back_inserter(buf));
// данные прочитались успешно?
if( istr.good() )
{
    ...
}
Re[2]: istreambuf_iterator
От: GregZ СССР  
Дата: 06.10.05 11:29
Оценка:
Здравствуйте, Анатолий Широков, Вы писали:

АШ>
АШ>std::copy(std::istream_iterator<char>(istr), std::istream_iterator<char>(), std::back_inserter(buf));
АШ>// данные прочитались успешно?
АШ>if( istr.good() )
АШ>{
АШ>    ...
АШ>}
АШ>


Это верно для istream_iterator.
istreambuf_iterator работает с буфером потока, и установить флаги ошибок не может.
Re[3]: istreambuf_iterator
От: Кодт Россия  
Дата: 06.10.05 12:59
Оценка:
Здравствуйте, GregZ, Вы писали:

GZ>istreambuf_iterator работает с буфером потока, и установить флаги ошибок не может.


Может быть, нужно заставить поток выполнить пустые действия, обновляющие статус:
if(!ist.eof()) istr.peek();

Перекуём баги на фичи!
Re[4]: istreambuf_iterator
От: GregZ СССР  
Дата: 06.10.05 13:19
Оценка:
Здравствуйте, Кодт, Вы писали:

Все оказалось гораздо хуже, чем я думал.
(немного отойду от темы)

Как известно, при чтении файла по достожении его конца (успешном) устанавливаются одновременно 2 флага: eof и fail.

Ситуация такова, что я читаю файл, находящийся на дискете. (Файл не читается где-то на половине).
Так вот, код приведеный ниже читает читабельный кусок файла. Установленные флаги: eof и fail.

т.е. никакой реальной возможно понять правильно ли прочитался файл нет?

Код:
(читаю специально istreambuf_iterator чтобы устанавливались флаги)

  std::copy(std::istream_iterator<char>(istr), std::istream_iterator<char>(), std::back_inserter(buf));
Re: istreambuf_iterator
От: Глеб Алексеев  
Дата: 06.10.05 13:30
Оценка:
Здравствуйте, GregZ, Вы писали:

GZ>Как используя istreambuf_iterator понять, что при чтении произошла ошибка?

А что считать ошибкой?
Такое впечатление, что у istreambuf_iterator ошибок быть не может, только конец файла — следовательно, если есть уверенность, что символов должон быть не меньше n, проверяем размер buf после copy и делаем выводы.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[2]: istreambuf_iterator
От: GregZ СССР  
Дата: 07.10.05 05:54
Оценка:
Здравствуйте, Глеб Алексеев, Вы писали:

ГА>Здравствуйте, GregZ, Вы писали:


GZ>>Как используя istreambuf_iterator понять, что при чтении произошла ошибка?

ГА>А что считать ошибкой?
Например невозможность буфером прочитать данные из устройства ввода (здесь дискета).

ГА>Такое впечатление, что у istreambuf_iterator ошибок быть не может, только конец файла — следовательно, если есть уверенность, что символов должон быть не меньше n, проверяем размер buf после copy и делаем выводы.


А у istream_iterator итератора? Я имел ввиду именно его (см. пример). Скопипастил не оттуда
Ясное деле, что istreambuf_iterator не может устанавливать флаги — он же работает с буфером.



Покопался в стандарте. Оказывается:
Виртуальная функция basic_streambuf<>::underflow (на самом деле выполняющая чтение из устройства ввода) в случае ошибки чтения возвращает EOF, то есть признак невозможности дальнейшего чтения. Какая ошибка — не определяется. Это может быть как конец файла, так и ошибка чтения из файла.
Такое поведение потокового буфера открыло мне глаза на то, что я долго не мог понять: почему флаг eof устанавливается вместе с флагом fail при попытке чтения символа за концом файла.
Я, наивная душа, думал, что флаг fail, предназначен для индикации hardware ошибки чтения (типичный случай самогипноза — я даже предположить не мог что ошибки оборудования никому не нужны). А ведь был в некоторый старых реализациях флаг hard! Теперь меня наконец-то разубедили.

Вывод: в стандартной библиотеке потоков НЕТ возможности определить hardware ошибку чтения. А раз ее нельзя определить чтеним из потока с помощью istreambuf_iterator, то нельзя и с помощью istream_iterator.

Вообще у меня все больше складывается впечатление, что потоки стандартной библиотеки напоминают мамонтов.
Огромные, неповоротливые и неизбежно вымрут.
Re[3]: istreambuf_iterator
От: Глеб Алексеев  
Дата: 07.10.05 07:38
Оценка:
Здравствуйте, GregZ, Вы писали:

GZ>Вывод: в стандартной библиотеке потоков НЕТ возможности определить hardware ошибку чтения. А раз ее нельзя определить чтеним из потока с помощью istreambuf_iterator, то нельзя и с помощью istream_iterator.

Я думаю, в твоем случае можно средствами ОС узнать размер файла и сравнить с объемом прочитанных данных (если читаешь в двоичном режиме).

GZ>Вообще у меня все больше складывается впечатление, что потоки стандартной библиотеки напоминают мамонтов.

GZ>Огромные, неповоротливые и неизбежно вымрут.
Все там будем.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[4]: istreambuf_iterator
От: GregZ СССР  
Дата: 07.10.05 07:54
Оценка:
Здравствуйте, Глеб Алексеев, Вы писали:

ГА>Я думаю, в твоем случае можно средствами ОС узнать размер файла и сравнить с объемом прочитанных данных (если читаешь в двоичном режиме).

Спасибо, сам уже о таком подумывал.
Только не дело это. Как быть с ситуацией, если поток не поддерживает позиционирование, и узнать размер данных нельзя?
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.