ПА>Ламерский вопрос Почему ламерский? Нормальный вопрос, который обычно встречается большинству программеров. ПА>Есть у меня некая структура (struct). ПА>Требуется создать файл, куда писать данные в виде этих структур. А также читать. А также перемещаться по файлу. ПА>Как это сделать? (Плиз с ма-аленьким примером или в какую сторону копать). Всё зависит от многих вещей, как всегда Для начала давай объявим твою структуру:
Теперь, допусти, нам нужно положить её в файл средствами C/C++. Семейсво функций FILE рассматривать не будет в связи с её архаичносью, и начнём сразу с варианта, который не входит в стандарт, но присутствует во многих компиляторах.
Эта программа открывает файл (либо создаёт его при необходимости) и добавляет в него новую структуру, затем читает первый экземпляр. Всё казалось бы нормально, но если ты посмотришь размер созддаваемого файла, то он всегда будет кратен 24 байтам (вариант Visual C++), хотя размер структуры равен 4+5+8=17 байт. Это происходит потому, что компиляторы по умолчанию выравнивают размер структур в целях оптимизации. Следовательно, наша первая задача отменить это поведение по умолчанию. Стандартных средств сделать это нет, но как правило компиляторы содержат специальную опцию коммандной строки и/или прагму, позволяющую это делать. Ещё одной неверной деталью в нашем примере является использование типа переменной int. Для разных версий операционных систем размер инта может быть разным и лучше явно указать размер используемого типа — short или long. Изменим описание структуры:
Теперь запись в файл даст вполне ожидаемый результат. Здесь можно отметить ещё одну деталь. В качестве строки я использовал массив char[5]. Использование классов типа CString std::string не приведёт ни к чему хорошему. Фактически ты сохранишь не саму строку, а содержимое класса, который её реализует. Допустим, класс CMyString реализован следующим образом:
Объявление такой структуры как
будет фактически соответствовать следующему варианту:
Т.е. в месте, где ты ожидаешь строку будет указатель на буфер в памяти, который (в смысле не буфер, а указатель на него) ты благополучно и сохранишь в файле. Теперь рассмотрим вариант с потоками. Вообще-то, лучше конечно использовать новую версию <fstream>, но у меня она до сих не вызывает никакого доверия. По-этому, воспользуемся старым вариантом:
Ниже вариант использования Windows API вместо фуекций CRTL:
И т.д. Еще можно привести вариант исользования класса CFile из MFC, но, в принципе, он будет не очень сильно отличаться. Может я немного увлёкся, но главное чтобы было понятно ЗЫ. Далше тебя ждут другие вопросы:
Правильный ответ — не вычислять это по размеру файла, а добавить в начало заголовок (специальную структуру), содержащую необходимую служебную информацию: фактический размер файла, версию формата, число записей, смещение к первому блоку и т.п. Как добавлять записи переменной длины? Можно к каждой записи добавить свой заголовок, описывающий её структуру. Как удалять ненужные записи из файла? Можно просто помечать их как удалённые, а в последствии организовать упаковку файла. Можно организовать список удалённых страниц и использовать их в дальнейшем вместо добавления новых в конец. Как обеспечить совместный доступ к файлу из нескольких программ. Блокировки, отдельный сервер доступа и ещё куча всяких вариантов. Как сделать динамическую структуру записей в файле... У-у-у... Шутю я, шутю. |