C不会从文件加载信息(fread,fwrite)

时间:2016-12-07 12:03:06

标签: c arrays struct fwrite fread

#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;
    }
}

我有一个编写程序,它可以将一些数据输入到文件中,并且可以从该文件中读取该数据,问题可能是fwrite或fread,看起来每次我尝试加载并写入时都会崩溃来自文件的数据。任何想法为什么它不能正常工作?我甚至可以这样做,因为它是动态结构数组。提前谢谢。

1 个答案:

答案 0 :(得分:2)

为了将结构保存到文件中,它必须只包含标量值,而不是指向内存对象的指针。修改您的结构以使用数组而不是指针:

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

并相应地修改代码,但请注意:

  • 在文件中保存和读取结构需要以二进制模式"wb""rb"打开它。
  • 命名二进制文件array.txt 非常误导
  • 在写入文件时不需要传递计数地址,但是在读取时需要传递数组指针的地址,因为你还不知道要分配多少内存。

以下是修改后的代码:

#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;
}