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