0

I'm just trying to write a Point structure in binary file and to read the written structure.

Can someone explain me why this code is not working ?

#include<stdio.h>
#define N 100

typedef struct Point Point;
struct Point{
    float x;
    float y;
};

void initialisePoint(Point * p);
void showPoint(Point * p);
void initialiseFileName(char * fileName);
int writePointToFile(char * fileName, Point * p);
int readPointFromFile(char * fileName, Point * p);

int main()
{
    Point p1 = {0};
    Point p2 = {0};
    char fileName[N] = {0};
    int exitStatus = 0;

    initialisePoint(&p1);
    showPoint(&p1);

    initialiseFileName(fileName);

    printf("Vous avez entré : %s\n", fileName);

    printf("Write return : %d\n", writePointToFile(fileName, &p1));

    printf("Read return : %d\n", readPointFromFile(fileName, &p2));

    showPoint(&p2);

    return exitStatus;
}

void initialisePoint(Point * p){
    printf("Entrez une valeur pour x : ");
    scanf("%f", &p->x);
    printf("Entrez une valeur pour y : ");
    scanf("%f", &p->y);
}
void showPoint(Point * p){
    printf("Le point est aux coordonnées (x,y) = (%.2lf, %.2lf).\n", p->x, p->y);
}
void initialiseFileName(char * fileName){
    printf("Entrez une valeur pour le nom de fichier : ");
    scanf("%s", fileName);
}
int writePointToFile(char * fileName, Point * p)
{
    FILE* f2 = NULL;

    f2 = fopen(fileName, "wb");

    if(f2 != NULL){
        if(fwrite(&p, sizeof(struct Point), 1, f2) != 1){
            printf("Could not write to file.");
            fclose(f2);
            return -1;
        }
    }
    else
    {
        printf("Could not open file.");
        return -1;
    }
    fclose(f2);
    return 0;
}
int readPointFromFile(char * fileName, Point * p){

    FILE* f = NULL;

    f = fopen(fileName, "rb");

    if(f != NULL){
        if(fread(&p, sizeof(struct Point), 1, f) != 1){
            printf("Could not read from file.");
            fclose(f);
            return -1;
        }
    }
    else{
        printf("Could not open file.");
        return -1;
    }
    fclose(f);
    return 0;
}

There is my log :

/home/sviktor/CLionProjects/untitled/cmake-build-debug/untitled Entrez une valeur pour x : 2.33 Entrez une valeur pour y : 1.34 Le point est aux coordonnées (x,y) = (2.33, 1.34). Entrez une valeur pour le nom de fichier : test123.bin Vous avez entré : test123.bin Write return : 0 Read return : 0 Le point est aux coordonnées (x,y) = (0.00, 0.00).

Process finished with exit code 0

I'm working on Fedora and clion IDE,

Bless editor says that my test123.bin file contains this C4 2E 18 F1 FC 7F 00 00 but the read function is not working (it's giving point = (0,0))

Grechka Vassili
  • 853
  • 4
  • 15
  • 32
  • What do you see if you check your output file with a hexeditor? Was it written correctly? – Retr0id Sep 08 '17 at 19:28
  • What does "not working" mean? – nicomp Sep 08 '17 at 19:30
  • 1
    When calling `fread` and `fwrite`, try passing `p` instead of `&p` as the first parameter. `p` is the address of the structure; `&p` is the address of the pointer variable holding the address of the structure. The latter is a bit too much, I suppose. – Ruud Helderman Sep 08 '17 at 19:32
  • 1
    `fread(&p, sizeof(struct Point)` ==> `fread(p, sizeof(struct Point)` - note the first parameter. – WhozCraig Sep 08 '17 at 19:32
  • 1
    There is more wrong to it than just this though. Generally, you should **not** write structures to a file like this. There is no guarantee on the actual layout of the structure, so it's very possible that recompiling your program on another compiler, or a later version of same compiler, or the exact same compiler with different options will make your program incompatible with the files you saved. You should implement [proper serialization](https://stackoverflow.com/questions/6002528/c-serialization-techniques) instead, writing values in a controlled way. – spectras Sep 08 '17 at 19:38
  • Thank you guys, I'm a litle surprised that the IDE did not given any warning for this... Specially thank to @spectras to show me how to go deeper with this ! – Grechka Vassili Sep 08 '17 at 19:44

1 Answers1

3

Since your writePointToFile() and readPointFromFile() functions accept a pointer to your Point structure, you want to pass that pointer to fread and fwrite. It's a pointer your data, which is what you want to read and write. Your code is incorrectly passing a pointer to that pointer.

In other words, in writePointToFile(), you want to change the call

fwrite(&p, sizeof(struct Point), 1, f2)

to

fwrite(p, sizeof(struct Point), 1, f2)

and similarly for the fread call in readPointFromFile().

Steve Summit
  • 45,437
  • 7
  • 70
  • 103