Запись структуры в файл && чтение структуры в динамически выделенную память - PullRequest
0 голосов
/ 04 июня 2018

Я пытаюсь записать структуру в файл, а затем прочитать структуру в динамически выделенную память.Если этот алгоритм даже работает, я не уверен насчет функции fread ... Может ли он прочитать все структуры в файле, записанном таким образом, и сохранить его в * ptr, чтобы я мог получить к нему доступ из памяти?Есть ли лучший способ сделать это?

 typedef struct num {
    int num1;
    int num2;   
}NR;

void write() {
    int successfullywritten;
    FILE *f;
    struct num nr;
    f = fopen("dat.txt", "a");
    printf("Enter first number\n");
    scanf("%d", &nr.num1);
    printf("Enter second number\n");
    scanf("%d", &nr.num2);
    successfullywritten=fwrite(&nr, sizeof num, 1, f);
    printf("Succesfully written: %d\n", successfullywritten);
    fclose(f);
}

void read() {

    int size, entrys,i,successfullyread;
    FILE *f;
    f = fopen("dat.txt", "r");
    struct num *ptr;
    fseek(f, 0L, SEEK_END);
    size = ftell(f);
    printf("\nSize of file dat.txt: %d\n", size);
    entrys = size / sizeof(num);
    ptr = (num*)malloc(entrys * sizeof(num));
    successfullyread=fread(ptr, sizeof(num), entrys, f);
    printf("sucessfully Read: %d\n", successfullyread);
    for (i = 0;i < entrys; i++) {
        /*fread((ptr+i), sizeof(ptr), 1, f);*/
        printf("%d  ", (*(ptr)).num1);
        printf("%d\n", (*(ptr)).num2);

    }
    printf("\n");printf("\n");

    fclose(f);
}

int main() {
    int n;
    while(1){
       printf("Chooose action:\n1) write to file\n2) read from file:\n");
       scanf("%d", &n);
       switch (n) {
          case 1:
             write();
             break;
          case 2:
             read();
             break;
       }
    }
    return 0;
}

1 Ответ

0 голосов
/ 04 июня 2018

Во-первых, существует много простых опечаток, таких как

  • Существует путаница между именем с определением типа или именем структуры.Это entrys = size / sizeof(num); должно быть entrys = size / sizeof(struct num);
  • Это ptr = (num*)malloc(entrys * sizeof(num)); должно быть ptr = malloc(entrys * sizeof(struct num));.Избегайте результата чтения malloc().

Во-вторых, найдя size, вы забыли переместить f в начало файла.например,

fseek(f, 0L, SEEK_END);
size = ftell(f);
fseek(f, 0L, SEEK_SET); /* you forgot to add this */ 

В-третьих, вы вводите данные в файл, используя fwrite(), используйте ab вместо a, а при чтении, используя fread(), используйте rb вместо r.

Также после чтения из файла вам нужно освободить ptr, чтобы избежать утечки памяти.

free(ptr);

Вот пример кода

typedef struct num {
        int num1;
        int num2;
}NR;
void my_write(void) {
        int successfullywritten;
        FILE *f;
        struct num nr;
        f = fopen("dat.txt", "ab");
        printf("Enter first number\n");
        scanf("%d", &nr.num1);
        printf("Enter second number\n");
        scanf("%d", &nr.num2);
        successfullywritten=fwrite(&nr, sizeof(nr), 1, f);
        printf("Succesfully written: %d\n", successfullywritten);
        fclose(f);
}

void my_read(void) {

        int size, entrys,i,successfullyread;
        FILE *f;
        f = fopen("dat.txt", "rb");
        struct num *ptr;
        fseek(f, 0L, SEEK_END);
        size = ftell(f);
        fseek(f, 0L, SEEK_SET);
        printf("\nSize of file dat.txt: %d\n", size);
        entrys = size / sizeof(struct num);

        ptr = malloc(entrys * sizeof(struct num));
        successfullyread=fread(ptr, sizeof(struct num), 2, f);
        printf("sucessfully Read: %d\n", successfullyread);

        for (i = 0;i < entrys; i++) {
                /*fread((ptr+i), sizeof(ptr), 1, f);*/
                printf("%d  ", ptr[i].num1);
                printf("%d\n", ptr[i].num2);

        }
        free(ptr);
        printf("\n");printf("\n");
        fclose(f);
}
int main(void) {
        int n;
        while(1){
                printf("Chooose action:\n1) write to file\n2) read from file:\n");
                scanf("%d", &n);
                switch (n) {
                        case 1:
                                my_write();
                                break;
                        case 2:
                                my_read();
                                break;
                }
        }
        return 0;
}
...