Создать базу данных мониторов - C (СИ)

Узнай цену своей работы

Формулировка задачи:

Имеется курсач - создать базу данных мониторов. Сейчас надо организовать бинарный файловый ввод/вывод структуры с помощью fread()/fwrite(). Память под записи выделяется динамически, записи объединены двусвязным списком. Проблемы сейчас следующие: 1) не работает

while( !feof(fp) )

: (строка 79 ) - при открытии пустого файла пропускает в цикл; - при открытии файла с записями при достижении (?) конца файла опять пропускает в цикл; Не понимаю, где находится маркер потока ввода после открытия файла. При добавлении

putc(fp)

начинает ловить EOF пустого файла, в записанном, естественно, съедает первый байт и на выводе получается каша. Пробовал сдвигать маркер ввода

fseek()

на 1, 2 и 3 байта - всё-равно пропускает в цикл. Получается при открытии файла маркер потока ввода находиться за файлом (вроде равен нулю, а не первому байту, где стоит EOF) или как? 2) После считывания записей из файла убивает сортировки записей (пузырьком и вставками ) в

segmentation fault

. Код сортировок здесь не привожу, смысла нет. Просто подскажите в каком виде эта считанная из файла структура попадает в память: становятся ли бывшие строки строками, приводятся ли числа к своим типам. В той же сортировке пузырьком по полю

size[]

ошибку выбивает на первом же этапе сравнения строк по длине через

strlen()

. Тут у меня никаких идей нет, разве что строки не закрыты '\0'? Код такой:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
 
struct base
{
   char name[30];
   float power;
   char size[11];
   unsigned long long int color;
   struct base * next, * prev;
};
 
struct base * load( FILE * , struct base * );               /* функция считывания из файла */
void close( FILE * , struct base * , struct base * , struct base * , const char * const );      /* функция записи в файла */
 
int main( int argc , char * argv[] )
{
   unsigned short num;
   struct base * first = NULL , * begin = NULL , * last = NULL;
   FILE * fp = NULL;
 
   /* обработка открытия файла */
   if( argc != 2 )
   {
      fputs("\n################################################################\n"
            "##   Файл для сохранения БД отсутствует!                      ##\n"
            "##   После закрытия программы вся работа с БД будет утеряна!  ##\n"
            "##   Для подключения файла введите первым ключом его имя.     ##\n"
            "################################################################\n" , stdout);
      fputs("\nДля продолжения нажмите Enter...\n" , stdout);
      getchar();
   }
   else if( argc == 2 && ( fp = fopen( argv[1] , "rb+") ) == NULL )
   {
      printf("Файл недоступен - %s\n", argv[1]);
      exit(1);
   }
   else if( argc == 2 && fp != NULL )
   {
      fprintf(stdout , "Файл \"%s\" открыт для считывания...\n", argv[1]);
      first = load( fp , first );
 
      /* флаг начального указателя; если begin и first различны - переписать файл БД */
      begin = first;
 
      /* последный указатель на данные из файла */
      for( last = first ; first != NULL && last->next != NULL ; last = last->next );      
   }

   /* далее меню */
   while( 1 )
   {
      system("clear");
 
      fputs("Работа с базой данных мониторов.\n"
            "\nВыберите нужный пункт:\n"
            /* часть кода пропущена */
            "9. Завершить работу с базой.\n" , stdout);
      while( scanf("%hu", &num) != 1 || num == 0 || num > 9 )
      { puts("Неверный ввод!\nПовторите ввод:"); getchar(); }
 
      system("clear");
 
      switch(num)
      {
         /* часть кода пропущена */
         case 9: close( fp , begin , first , last , argv[1] );            
               fputs("Работа завершена!\n" , stdout);
               exit(0);
      }
   }
}
 
struct base * load( FILE * fp , struct base * first )
{
   unsigned int num = 0;
   struct base * current, * down = NULL;
 
   while( !feof(fp) )      /* почему-то не работает? */
   {
      /* динамически выделяется память */
      current = (struct base *) malloc( sizeof(struct base) );
      if( current == NULL )
      {
         fputs("Ошибка инициализации памяти!\n" , stderr);
         exit(2);
      }
 
      if( first == NULL )
         first = current;                   /* флаг первой записи */
      else if( down == NULL )              /* в этом входе в load() записи ещё не вводились! */
      {
         down = first;
         while( down->next != NULL )      /* пробежда имеющихся записей при каждом входе в функцию */
         {
            down = down->next;
            num++;
         }
         num++;
         down->next = current;
      }
      else
         down->next = current;
 
      current->next = NULL;
      current->prev = down;
      down = current;               /* в начале цикла создастся новый current */

      /* начинает считывать из файла */
      if( fread( current , sizeof(struct base) , 1 , fp ) != 1 )
      {
         if( feof(fp) )
            break;
 
         fprintf( stderr , "Запись #%u.\nОшибка считывания!\n" , num);
         exit(3);
      }
      else
         num++;
   }
 
   num ? fprintf(stdout , "Из файла считано %u записей.\n", num) : fputs("Файл пуст.\n" , stdout);
   fputs("\nДля продолжения нажмите Enter...\n" , stdout);
   getchar();
   return first;
}
 
            /* указ. на 1-ю запись из файла , текущий 1-ый указ. БД , указ. на последнюю запись из файла */
void close( FILE * fp , struct base * begin , struct base * current , struct base * last , const char * const argv )
{
   unsigned int num;
 
   if( fp != NULL )
   {
      /* если begin и first различны - переписать файл БД */
      if( current != begin )
      {
         rewind(fp);
         last = current;
      }
      else 
         last = last->next;
 
      for( num = 1 ; last != NULL ; ++num , last = last->next )
         if( fwrite( last , sizeof(struct base) , 1 , fp ) != 1 )
         {
            fprintf( stderr , "Запись #%u.\nОшибка записи!\n" , num );
            exit(3);
         }
 
      if( fclose(fp) != 0 )
      {
         fprintf(stderr , "Невозможно сохранить файл - %s\n", argv);
         exit(1);
      }
   }
 
   while( current != NULL )
   {
      free(current);
      current = current->next;
   }
 
   return;
}

Решение задачи: «Создать базу данных мониторов»

textual
Листинг программы
if( feof(fp) )

ИИ поможет Вам:


  • решить любую задачу по программированию
  • объяснить код
  • расставить комментарии в коде
  • и т.д
Попробуйте бесплатно

Оцени полезность:

14   голосов , оценка 4.143 из 5