Создать базу данных мониторов - 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) )
ИИ поможет Вам:
- решить любую задачу по программированию
- объяснить код
- расставить комментарии в коде
- и т.д