Фича в стандартной библиотеке С++, ifstream::seekg иногда не работает |
Здравствуйте, гость ( Вход | Регистрация )
Фича в стандартной библиотеке С++, ifstream::seekg иногда не работает |
Iron Bug |
5.10.2012, 14:46
Сообщение
#1
|
Профессионал Группа: Модератор Сообщений: 1611 Регистрация: 6.2.2009 Из: Yekaterinburg Пользователь №: 533 Спасибо сказали: 219 раз(а) Репутация: 12 |
В общем, напоролась я на фичу (как оказалось, а не багу), потратила кучу времени. Хочу предупредить всех, что она есть.
Проблема в том, что в стандартном ifstream, после чтения до конца файла (eof()), функция seekg работать перестаёт. Вот простой код, который даёт неравные буферы:
решение проблемы - сброс бита: перед вызовом seekg() вызывать clear(). можно ещё переоткрыть файл - тоже, естественно, сработает. главное, знать об этом косяке Сообщение отредактировал Iron Bug - 5.10.2012, 15:46 |
|
|
ssoft |
5.10.2012, 15:21
Сообщение
#2
|
Участник Группа: Участник Сообщений: 130 Регистрация: 17.2.2010 Из: Москва Пользователь №: 1470 Спасибо сказали: 30 раз(а) Репутация: 3 |
Дак вроде так везде работает, не только под MSVS.
При достижении конца выставляется статус eofbit (тип iostate), аля кутешного ReadPastEnd. Пока статус не изменится с помощью clear() на goodbit (в Qt resetStatus() изменяет на Ok) ничего с потоком сделать нельзя, в том числе и вернуться в начало. Сообщение отредактировал ssoft - 5.10.2012, 15:34 |
|
|
Iron Bug |
5.10.2012, 15:44
Сообщение
#3
|
Профессионал Группа: Модератор Сообщений: 1611 Регистрация: 6.2.2009 Из: Yekaterinburg Пользователь №: 533 Спасибо сказали: 219 раз(а) Репутация: 12 |
Дак вроде так везде работает, не только под MSVS. При достижении конца выставляется статус eofbit (тип iostate), аля кутешного ReadPastEnd. Пока статус не изменится с помощью clear() на goodbit (в Qt resetStatus() изменяет на Ok) ничего с потоком сделать нельзя, в том числе и вернуться в начало. действительно. я дома под линём проверила только что. значит, просто я столько лет не знала о такой странной фиче. видимо, никогда не пыталась перемещаться по файлу после прочтения его до конца, а тут понадобилось. и всё же, почему eof считается "ошибкой" - мне непонятно. обычный статус потока, почему его нужно обрабатывать как-то отдельно - полная загадка. ладно, переименую тему, чтобы было более адекватно. |
|
|
Litkevich Yuriy |
7.10.2012, 14:05
Сообщение
#4
|
разработчик РЭА Группа: Сомодератор Сообщений: 9669 Регистрация: 9.1.2008 Из: Тюмень Пользователь №: 64 Спасибо сказали: 807 раз(а) Репутация: 94 |
Да бага это однозначно, просто авторы отмазываются.
Если некая функция позволяет устанавливать указатель куда-нибудь, значит он должен безоговорочно устанавливаться. Единственное место в котором бессмысленна установка указателя - последовательные интерфейсы. |
|
|
Iron Bug |
8.10.2012, 9:08
Сообщение
#5
|
Профессионал Группа: Модератор Сообщений: 1611 Регистрация: 6.2.2009 Из: Yekaterinburg Пользователь №: 533 Спасибо сказали: 219 раз(а) Репутация: 12 |
Да бага это однозначно, просто авторы отмазываются. Если некая функция позволяет устанавливать указатель куда-нибудь, значит он должен безоговорочно устанавливаться. Единственное место в котором бессмысленна установка указателя - последовательные интерфейсы. ну вот как бы и я так же думала: раз это файл, то ползать по нему можно туда-сюда без ограничений. а оказалось, что eof его переводит в какое-то особое невменяемое состояние и надо ещё отслеживать, был ли этот eof. с моей точки зрения, это маразм, конечно. если я на начало файла перевожу указатель чтения, то какая мне разница, был он в конце или в середине... тем не менее, вот так вот реализовано. причём везде. Сообщение отредактировал Iron Bug - 8.10.2012, 9:09 |
|
|
Влад |
8.10.2012, 15:49
Сообщение
#6
|
Участник Группа: Участник Сообщений: 146 Регистрация: 20.3.2009 Из: Санкт-Петербург Пользователь №: 627 Спасибо сказали: 46 раз(а) Репутация: 8 |
Это не отмазка, а точное следование требованию Стандарта языка.
Бит eofbit устанавливается в момент попытки чтения за концом файла - естественно, попытка эта неудачная; и поэтому одновременно устанавливается failbit. В соответствии с буквой Стандарта (27.7.2.3, cl.41,43), операция seekg() игнорируется до тех пор, пока не будет сброшен failbit. |
|
|
Iron Bug |
9.10.2012, 20:21
Сообщение
#7
|
Профессионал Группа: Модератор Сообщений: 1611 Регистрация: 6.2.2009 Из: Yekaterinburg Пользователь №: 533 Спасибо сказали: 219 раз(а) Репутация: 12 |
просто стандарт слишком древний. он не соответствует нормальной логике потоков со свободным доступом это типичный лишний вызов. если я хочу переместиться а абсолютный старт потока со свободным доступом - это всегда возможно, где бы ни находился указатель. возможно, стандарт писали, когда файлы хранились на каких-нибудь первобытных устройствах типа лент.
в общем, проще написать обёртку, которая перегружает это дело, проверяет и сбрасывает этот никому не нужный бит, юзать её и не париться. |
|
|
Влад |
9.10.2012, 21:01
Сообщение
#8
|
Участник Группа: Участник Сообщений: 146 Регистрация: 20.3.2009 Из: Санкт-Петербург Пользователь №: 627 Спасибо сказали: 46 раз(а) Репутация: 8 |
Хмм... Называть 14882-2011 "слишком древним" я бы, пожалуй, не стал бы... :-)
|
|
|
Iron Bug |
10.10.2012, 6:55
Сообщение
#9
|
Профессионал Группа: Модератор Сообщений: 1611 Регистрация: 6.2.2009 Из: Yekaterinburg Пользователь №: 533 Спасибо сказали: 219 раз(а) Репутация: 12 |
|
|
|
Влад |
10.10.2012, 9:41
Сообщение
#10
|
Участник Группа: Участник Сообщений: 146 Регистрация: 20.3.2009 Из: Санкт-Петербург Пользователь №: 627 Спасибо сказали: 46 раз(а) Репутация: 8 |
Может, забыли, а может - нет.... Мы не знаем всех соображений, которыми руководствовался Комитет (а работают там отнюдь не глупые люди).
Я бы предложил тебе написать письмо с обоснованием в WG21 - они довольно объективно принимают предложения по совершенствованию Стандарта. Я допускаю, что были какие-то основания написать в Стандарте именно так, а не иначе, - какие именно, будет ясно из ответного письма. Из известных мне случаев (писал предложения не я), ответ приходит всегда, - даже если это вежливый отказ. По крайней мере, если твое предложение не будет принято, мы через пару месяцев будем четко знать, почему Стандарт требует делать так, а не иначе. |
|
|
Текстовая версия | Сейчас: 30.1.2025, 5:31 |