简体   繁体   English

C不会从文件中加载信息(读取,写入)

[英]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. 我要写一个程序,将一些数据输入文件并可以从该文件中读取数据,问题可能出在fwrite或fread上,因为每次我尝试加载文件并从文件中写入数据时似乎崩溃了。 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" . 保存和读取文件中的结构需要以二进制模式"wb""rb"打开它。
  • it is very misleading to name a binary file array.txt . 将二进制文件命名为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;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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