简体   繁体   中英

C doesn't load info from file (fread, fwrite)

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define SLENG   50 //just a random value

typedef struct Song 
{
    char *name;
    char *nameSong;
    char *timeSong;
    int date;
}  Song;

void saveToFile(Song *x, int *songCount) //Saves info  to the binary file
{
    FILE *f = fopen("array.txt", "w");
    if (f == NULL)
    {
        printf("Error\n");
    }
    fwrite(songCount, sizeof(int), 1, f);
    fwrite(x, sizeof(struct Song), (*songCount), f);
    fclose(f);
}

void readSong(Song *x, int *songCount) //Reads info fromt he file and writes it
{
    FILE *fr = fopen("array.txt", "r");
    if (fr == NULL)
    {
        printf("Error\n");
    }
    printf("Songs:\n");
    fread(songCount, sizeof(int), 1, fr);
    fread(x, sizeof(struct Song), (*songCount), fr);
    for(int i=0; i < (*songCount); i++)
    {
        printf("%d. %s %s %s %d\n", (i+1), x[i].name, x[i].nameSong, x[i].timeSong, x[i].date);
    }
    fclose(fr);
}

void insertSong(Song *x, int Count) //Inserts new song into the array.
{
    printf("\nInsert name of the band:\n");
    x[Count].name=malloc(SLENG * sizeof(char));
    scanf("%s", x[Count].name);

    printf("Insert name of the song:\n");
    x[Count].nameSong=malloc(SLENG * sizeof(char));
    scanf("%s", x[Count].nameSong);

    printf("Insert length of the song:\n");
    x[Count].timeSong=malloc(SLENG * sizeof(char));
    scanf("%s", x[Count].timeSong);

    printf("Insert then song was created:\n");
    scanf("%d", &(x[Count].date));
    printf("\n");
}

main()
{
    int songCount, menuOption;
    Song *x=malloc(SLENG*sizeof(char)+SLENG*sizeof(char)+SLENG*sizeof(char)+sizeof(int));
    printf("1. insert song\n 2. load from file\n ");
    scanf("%d", &menuOption);
    switch(menuOption)
    {
        case(1) :
            printf("Insert how many songs do you want to input?\n");
            scanf("%d", &songCount);
            for(int i=0; i<songCount; i++)
            {
                insertSong(x, i);
            }
            saveToFile(x, &songCount);
            break;
        case(2) :
            readSong(x, &songCount);
            break;
    }
}

I have an assingment to write a programm which would input some data into file and could read that data from that file, the problem is probably with fwrite or fread, couse it seems to crash everytime I try to load the and write the data from file. Any ideas why is it not working properly? And can I even do it like this as it is dynamic struct array. Thanks in advance.

In order to save the structure to a file, it must only contain scalar values, not pointers into memory objects. Modify your structure to use arrays instead of pointers:

typedef struct Song {
    char name[SLENG];
    char nameSong[SLENG];
    char timeSong[SLENG];
    int date;
} Song;

And modify the code accordingly, but note that:

  • saving and reading the structures to and from a file requires opening it in binary mode "wb" and "rb" .
  • it is very misleading to name a binary file array.txt .
  • you do not need to pass the address of the count when writing to the file, but you need to pass the address of the array pointer when reading as you do not know yet how much memory to allocate.

Here is the modified code:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define SLENG   50   // this value is used in the file format

typedef struct Song {
    char name[SLENG];
    char nameSong[SLENG];
    char timeSong[SLENG];
    int date;
} Song;

int saveToFile(Song *x, int songCount) { //Saves info  to the binary file
    FILE *f = fopen("array.bin", "wb");
    if (f == NULL) {
        printf("Error\n");
        return -1;
    }
    fwrite(songCount, sizeof(int), 1, f);
    int written = fwrite(x, sizeof(struct Song), songCount, f);
    fclose(f);
    return written;
}

int readSong(Song **x, int *songCount) { //Reads info from the file and writes it
    int count = 0;
    FILE *fr = fopen("array.bin", "rb");
    if (fr == NULL)  {
        printf("Error\n");
        return -1;
    }
    printf("Songs:\n");
    fread(&count, sizeof(int), 1, fr);
    *x = calloc(count, sizeof(Song));
    if (*x == NULL) {
        printf("Cannot allocate %d bytes of memory\n", count);
        fclose(fr);
        return -1;
    }
    int found = fread(*x, sizeof(struct Song), count, fr);
    for (int i = 0; i < found; i++) {
        printf("%d. %s %s %s %d\n", i + 1,
               (*x)[i].name, (*x)[i].nameSong, (*x)[i].timeSong, (*x)[i].date);
    }
    fclose(fr);
    return *songCount = found;
}

void insertSong(Song *x, int Count) { //Inserts new song into the array.
    printf("\nInsert name of the band:\n");
    scanf("%49s", x[Count].name);

    printf("Insert name of the song:\n");
    scanf("%49s", x[Count].nameSong);

    printf("Insert length of the song:\n");
    scanf("%49s", x[Count].timeSong);

    printf("Insert then song was created:\n");
    scanf("%d", &(x[Count].date));
    printf("\n");
}

int main(void) {
    int songCount, menuOption;
    Song *x = NULL;

    printf("1. insert song\n 2. load from file\n ");
    scanf("%d", &menuOption);

    switch (menuOption) {
      case 1:
        printf("Insert how many songs do you want to input?\n");
        if (scanf("%d", &songCount) == 1) {
            x = calloc(songCount, sizeof(Song));
            for (int i = 0; i < songCount; i++) {
                insertSong(x, i);
            }
            saveToFile(x, songCount);
        }
        break;
      case 2:
        readSong(&x, &songCount);
        break;
    }
    free(x);
    x = NULL;

    return 0;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM