Thread: Problem writing structure within another structure to file

  1. #1
    Registered User
    Join Date
    May 2007
    Posts
    4

    Problem writing structure within another structure to file

    I'm having trouble writing the folowing structure to a binary file:

    Code:
    typedef struct
    {
       int day, month, year;        
    } Aval;
    
    typedef struct
    {
       char name[100], state[50];
       int freq, work;
       float *n_aval, final_note;   
       Aval *n_data;
    }CURSO;
    The program writes everything fine except the data of Aval type.
    This is the function I am using just to get the days, month and year to an array:

    Code:
    void Date_Eval(CURSO v[])
    {
       char aux[]="SIGNED", name[100], buff[256];
       int i, pos, j;
         
       fgets(buff,255,stdin);
           
       printf("\n");
       printf("LIST:\n");
       printf("\n");
          
       for(i=0;i<28;i++)
       {
          if((strcmp(aux,v[i].state))==0)   //print the disciplines that i signed in
             printf("%s\n", v[i].name);
       }
          
       gets(name);
          
       for(i=0;i<28;i++)
       {
          if((strcmp(name,v[i].name))==0) //store the position that the discipline is in, in the array
             pos=i;
       }
          if((v[pos].n_aval=(float*)realloc(v[pos].n_aval,sizeof(float)*(v[pos].freq+v[pos].work)))==NULL) //v[pos].freq+v[pos].work is the size of the array.
          {   
             printf("ERRO\n");
          }
          else
          {
             if((v[pos].n_data=(Aval *)realloc(v[pos].n_data,sizeof(Aval)*(v[pos].freq+v[pos].work)))==NULL) //v[pos].freq+v[pos].work is the size of the array.
             {   
                printf("ERROR\n");
             }
             else
             {   
                for(j=0;j<(v[pos].freq+v[pos].work);j++)
                {
                      printf("Day of evalutation %d: ", j+1);
                      scanf("%d",&v[pos].n_data[j].day);
               
                      printf("Month of evaluation %d: ", j+1);
                      scanf("%d",&v[pos].n_data[j].month);
                   
                   printf("Year of evaluation %d: ", j+1);
                   scanf("%d",&v[pos].n_data[j].year);
                }
             }
       }
    }
    The data is stored correctly in memory, because I can see it while in the program, but when I exit and enter again it's no longer there.

    I am reading in the begining:

    Code:
    if((f=fopen("Data.dat","rb"))==NULL)
       {
          printf("ERROR\n");
       }
       else
       {
            fread(v,sizeof(CURSO),28,f);  //--> 28 is the number of discipline i want to read
             ........................
    
    fclose(f);
    And only writing in the end:

    Code:
    if((f=fopen("Data.dat","wb"))==NULL)
       {
          printf("ERROR\n");
       }
       else
       {
          fwrite(v,sizeof(CURSO),28,f); //-->28 is the number is the number of disciplines i want to write.
       }
    fclose(f);
    I have tried opening and and writing in every function but the result is the same.
    If anyone could help...And sorry for my bad english.
    Thanks in advance.

  2. #2
    Woof, woof! zacs7's Avatar
    Join Date
    Mar 2007
    Location
    Australia
    Posts
    3,459
    You do realize your writing sizeof(CURSO) * 28 bytes.

    Also writing structures to disk in this manner isn't portable, whats to say another OS structures the struct the same way in memory as your own.

    You cannot write pointers to a file, once you close your program and load the file once more the address is invalid. I suggest writing the value of each element to a file yourself.

  3. #3
    Deathray Engineer MacGyver's Avatar
    Join Date
    Mar 2007
    Posts
    3,210
    To articulate a little bit more on that last point, let's trace what is happening when you try to write the struct to a file using fwrite().

    1) It writes the array name, all 100 bytes.
    2) It writesd the array state, all 50 bytes;
    3) It writes the vars freq and work;
    4) First problem: It writes the address of whatever the float pointer points to. Then it writes the var final_notes.
    5) Second problem: It writes the address of whatever n_data points to.

    I hope this helps you understand the problem better.

  4. #4
    Woof, woof! zacs7's Avatar
    Join Date
    Mar 2007
    Location
    Australia
    Posts
    3,459
    6) Writing a struct literally to a file isn't portable...

  5. #5
    Registered User
    Join Date
    May 2007
    Posts
    4
    Quote Originally Posted by MacGyver View Post
    To articulate a little bit more on that last point, let's trace what is happening when you try to write the struct to a file using fwrite().

    1) It writes the array name, all 100 bytes.
    2) It writesd the array state, all 50 bytes;
    3) It writes the vars freq and work;
    4) First problem: It writes the address of whatever the float pointer points to. Then it writes the var final_notes.
    5) Second problem: It writes the address of whatever n_data points to.

    I hope this helps you understand the problem better.
    Aval *n_data, and float *n_aval are two arrays which size I don't know. So I have to declare them with a pointer so i can alocate memory when i need to store values in the array. Am i right?
    So how do I then save that information in a binary file?
    I'm insisting on this because this is a work for university and i have to do it this way.
    Thanks again.

  6. #6
    Deathray Engineer MacGyver's Avatar
    Join Date
    Mar 2007
    Posts
    3,210
    Write a function to write a struct out to a file, and a sister function to read one from a file.

    Manually write/read the structs out, member by member.

  7. #7
    Registered User
    Join Date
    May 2007
    Posts
    4
    Ok thanks. I'm going to try that.

  8. #8
    Registered User
    Join Date
    May 2007
    Posts
    4
    Code:
    for(j=0;j<28;j++)
    { 
       fread(&v[j],sizeof(CURSO),1,f);     //for reading the file to the array
    }
    
    for(j=0;j<28;j++)
    { 
       fwrite(&v[j],sizeof(CURSO),1,f);   //for writing the array to the file
    }
    I tried this, i think that's what you were saying, am I right?
    I'm still havingthe same problem...

  9. #9
    Deathray Engineer MacGyver's Avatar
    Join Date
    Mar 2007
    Posts
    3,210
    *sigh*

    No. Write a function to write only one struct to a file. Call it something like writestruct(). Inside that function, write each member of the struct separately to the file. This means you should write, name, state, freq, and so on, using fread(). For each variable, use fread(). When you get to a pointer in the struct like n_aval, handle it specially by dereferencing it. Same with the other pointer you have to the other type of struct. Handle it specially.

    Call this function in a loop, so each struct object is passed to this function. That way every struct will be written to the file.
    Last edited by MacGyver; 05-20-2007 at 04:28 PM.

  10. #10
    Woof, woof! zacs7's Avatar
    Join Date
    Mar 2007
    Location
    Australia
    Posts
    3,459
    Astoria you have to take into endian issues into consideration (also struct padding), Writting each element as MacGyver has timelessly recommended will allow you to solve that problem, and write the values rather than the address of variables to the file.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. File Writing Problem
    By polskash in forum C Programming
    Replies: 3
    Last Post: 02-13-2009, 10:47 AM
  2. Data Structure Eror
    By prominababy in forum C Programming
    Replies: 3
    Last Post: 01-06-2009, 09:35 AM
  3. Problem referencing structure elements by pointer
    By trillianjedi in forum C Programming
    Replies: 19
    Last Post: 06-13-2008, 05:46 PM
  4. File Database & Data Structure :: C++
    By kuphryn in forum C++ Programming
    Replies: 0
    Last Post: 02-24-2002, 11:47 AM
  5. Writing a structure to file?
    By Unregistered in forum C Programming
    Replies: 2
    Last Post: 12-01-2001, 01:43 AM