Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Центр помощи > [C++] Чтение массива структур из бинарного файла


Автор: vladko 7.12.2009, 18:47
Бинарный файл состоит из заголовка:
Код

struct HistoryHeader
  {
   int               version;
   char              copyright[64];
   char              symbol[12];
   int               period;
   int               digits;
   time_t            timesign;
   time_t            last_sync;
   int               unused[13];
  };

и массива структур:
Код

#pragma pack(push,1)
struct RateInfo
  {
   time_t            ctm;
   double            open;
   double            low;
   double            high;
   double            close;
   double            vol;
  };
#pragma pack(pop)


читаю заголовок и 1 структуру из массива.
Код

struct HistoryHeader s;
struct QuoteInfo q;
....
stream = fopen("c:\\1.dat", "r");
 
   fread(&s, sizeof(s), 1, stream);
   fread(&q, sizeof(q), 1, stream);


Как прочитать оставшиеся до конца файла структуры и изменить последнюю?

Автор: t_gran 8.12.2009, 04:40
Цитата

Как прочитать оставшиеся до конца файла ...

Код

while (!eof(stream))
{
   fread(&s, sizeof(s), 1, stream);
   fread(&q, sizeof(q), 1, stream);
   // ... обработка
}


Цитата

... и изменить последнюю


А вот с этим проблемка. Придёться переписывать файл, т.к. в Си нет такой возможности заменять данные в файле. По крайней мере ни разу не встречал. Добавить можно, но не изменить.
Код

stream= fopen("c:\\1.dat", "ab+"); // открыть для чтения и записи в конец

Автор: vladko 8.12.2009, 06:13
Спасибо.
Может быть на каком-нибудь другом языке программирования возможно изменять файл?

Автор: Dancer 8.12.2009, 11:36
Цитата(t_gran @  8.12.2009,  04:40 Найти цитируемый пост)
в Си нет такой возможности заменять данные в файле.

вроде бы можно переместиься в определённое место, и оттуда уже производить запись. разьве нет?
peek(), fseek()

что-то вроде, c конца, вернулись на sizeof(q) и переписали эту структуру.
fseek(stream, -sizeof(q), SEEK_END);
fwrite(&new_q, sizeof(q), 1, stream);
fclose(stream);

Автор: mr.Anderson 8.12.2009, 20:57

 ! 
mr.Anderson
Модератор: название темы должно содержать язык написания!

Автор: t_gran 9.12.2009, 05:05
Dancer, перед тем как отвечать я обязательно проверил ваше предположение и к сожалению оно ошибочно.  Но если вы предоставите код, который будет выполнять это, я буду рад т.к. это и меня просвятит и в дальнейшем на пользу другим будет. А посему жду код. 

А то, что я пробовал, вот:
Код

#include <stdio.h>

int main (int argc, char **argv)
{
   FILE *f= fopen("file.txt", "ab+");
   if (!f)
   {
      puts("error: file not found ...");
      return 1;
   }
   char *qwe= "qwerty";
   fwrite(qwe, 6, 1, f);
   fseek(f, 0, SEEK_SET);
   fwrite("!", 1, 1, f);
   fclose(f);
   return 0;
}

И к моему сожалению получаю
Код

qwerty!

Автор: Dancer 9.12.2009, 12:22
Код

#include <stdio.h>

int main (int argc, char **argv)
{
    // "r+" will open a text file to read from or write to.
    // "w+" will create a text file to read from or write to.
    // Add a "b" to the end if you want to use binary files instead of text files, like this:
    // "rb", "wb", "ab", "r+b", "w+b", "a+b".

   FILE *f= fopen("file.txt", "r+b");
   if (!f)
   {
      puts("error: file not found ...");
      return 1;
   }

   char *qwe= "qwerty"; // 6 byte

   fseek(f, 0L, SEEK_END);
   fwrite(qwe, 6, sizeof(char), f);

   fseek(f, -1L, SEEK_END);
   fwrite("!2345", 2, sizeof(char), f); // write "!" and "2" only to file

   fseek(f, 0L, SEEK_SET);
   fwrite("SSS", 3, sizeof(char), f);

   fflush(f);
   fclose(f);

   return 0;
}


Автор: t_gran 10.12.2009, 03:30
Dancer, +1. Моей ошибкой был параметр a+b.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)