I need to create a file containing information about my personal book collection. The structure of the record: the book's cipher, author, title, year of publication, location (rack number, etc.).

Moreover, writing (input ()) and reading (output ()) structures are made to / from a file with the extension * .dat. With each new record, we, in fact, add a new structure. So, it does not work out for me to read normally. Displays only the last recorded. It also fails to introduce a new book cipher for the next structure, it just gets(B.key); misses.

 #include <stdio.h> #include <conio.h> #include <locale.h> #include <stdlib.h> void input(void); void output(void); struct cd { char key[12]; char author[30]; char title[20]; int year; int location; } B; FILE *f; void main(void) { int n = 0; system("cls"); setlocale(LC_CTYPE, "rus"); while(n != 3) { puts("1. Ввод данных в базу"); puts("2. Вывод всех авторов"); puts("Для выхода из программы нажмите любую другую клавишу..."); puts("\nВаш выбор: "); scanf("%d",&n); fflush(stdin); switch(n) { case 1: input(); break; case 2: system("cls"); output(); break; default: exit(1); } } } void input(void) { setlocale(LC_CTYPE, "rus"); int k = 0; if(( f = fopen("knigolub.dat","w")) == NULL) { puts("Невозможно открыть файл"); exit(1); } while (k != 10) { system("cls"); puts("Введите сведения о книге...\n\n"); printf("Введите шифр книги: "); gets(B.key); printf("Введите автора: "); gets(B.author); printf("Введите название: "); gets(B.title); printf("Введите год издания: "); scanf("%i", &B.year); printf("В какой стеллаж поместить? Введите его номер: "); scanf("%i", &B.location); fwrite(&B, sizeof(B), 1, f); puts("Продолжить работу?[y/n]"); char s; scanf("%s", &s); switch ((int) s) { case (int) 'y': return input(); case (int) 'n': return main(); } } } void output (void) { char letter; setlocale(LC_CTYPE, "rus"); if((f=fopen("knigolub.dat","r")) == NULL) { puts("Невозможно открыть файл"); exit(1); } printf("Шифр книги\tАвтор\tНазвание\tГод издания\tНомер стеллажа\n\n"); while ((letter == fgetc(f)) != EOF) { printf("%s\t%s\t%s\t%i\t%i\t\n", B.key, B.author, B.title, B.year, B.location); } getch(); system("cls"); fclose(f); } 
  • while ((letter == fgetc(f)) != EOF) { printf("%s\t%s\t%s\t%i\t%i\t\n", B.key, B.author, B.title, B.year, B.location); - this is, sorry, what is it? - PinkTux
  • @ pink-tux character reading from file - Nazariy
  • I guessed it was not line by line. But what should this delusional code do - you can even answer yourself? (why it is impossible to read fgetc in char - it is already so hard on the teeth that even to mention laziness ...) - PinkTux

2 answers 2

By * .dat usually imply some binary pseudoformat. Therefore, fw = fopen("knigolub.dat","wb")) and fr = fopen("knigolub.dat","rb")) and read-write through fread and fwrite. Let at the beginning of the file be the number of records ( size_t ):

 size_t count = 0; cd *buffer = NULL; fread (&count, sizeof(size_t), 1, fr); buffer = (cd*)malloc(sizeof(cd) * count); fread (buffer, sizeof(cd), count, fr); 

We write down, on the contrary, on the contrary - first we write the number, then the structures. If you need to add a structure to a file, we define the offset ( sizeof(size_t) + sizeof(cd)*count ), and then write the value in the number at the beginning of the file count + 1

    Displays only the last recorded.

    The point is not that it OUTPUTS the last recorded structure, but that when recording a new structure you overwrite (!!!) the previous one. Each time you call input (...) , you reopen the file:

     f = fopen("knigolub.dat","w") 

    At the same time, the previous contents of the file are LOSTED. It is necessary either:

    • Open once at the beginning of the entire program
    • Open with the addition attribute "a" (Open for appending: writing at end

    of file)