Thread: write structure to a file

  1. #1
    Registered User
    Join Date
    Jul 2011
    Posts
    18

    write structure to a file

    Guys before i post my problem , lemme say that, i HAVE gone through the previous blogs/forums on daniweb, so please dont get annoyed with this topic again.
    But none of them answer my question

    My question is, "How do you write a structure to a file and retrieve data from it.
    1)I think fwrite is the best option. Assuming s is the structure instance, you could use a code like
    Code:
    fwrite(&s,sizeof(s),1,fp);
    But the problem is, this doesnt work if the structure contains int.

    Why ?????
    Because, all though the 'int' is saved in the file(in disk), a text doc wont be able to display because it only displays ascii characters.

    2)So the way out would be to convery the number to a string , and then write into the file.So even the text doc will be able to display it char-by-char

    3)This sound logically flawless. But after converting the number to a string, how do you make that string also a part of the structure so that i can still do my
    Code:
    fwrite(&s,sizeof(s),1,fp);
    4)OK so i tried doing this. I am storing the number 0 as roll no. Notice the small tweak i did, 0 + '0'. So it displays even in the text doc cuz its actuallt printing ascii of (0+48). But clearly this doesnt work if the number is greater than 0.

    Code:
    #include<stdio.h>
    #include<conio.h>
    
    struct mystruct
    {
      int i;
      char ch;
    };
    
    int main(void)
    {
       FILE *fp;
       char* data;
       struct mystruct s;
       clrscr();
    
       if((fp= fopen("e:\\tc1\\bin\\tceg.txt", "wb")) == NULL) /* open file TEST.$$$ */
       {
          fprintf(stderr, "Cannot open output file.\n");
          return 1;
       }
       s.i = 0+'0';
       s.ch = 'A';
       fwrite(&s, sizeof(s), 1, fp); /* write struct s to file */
       fclose(fp); /* close file */
    
       rewind(fp);
       fp=fopen("e:\\tc1\\bin\\tceg.txt", "rb");
       fgets(data,100,fp);
       printf("\nThe data read from the file is : %s",data);
    
       getch();
       return 0;
    }
    5)Guys , so basically can you help me with a code that will take any integer (PART OF A STRUCTURE) and display it on the text doc.

  2. #2
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    Quote Originally Posted by tubby123 View Post
    Because, all though the 'int' is saved in the file(in disk), a text doc wont be able to display because it only displays ascii characters.
    Congratulations! You've just discovered the difference between a binary and text file.
    Quote Originally Posted by tubby123 View Post
    3)This sound logically flawless. But after converting the number to a string, how do you make that string also a part of the structure so that i can still do my
    Code:
    fwrite(&s,sizeof(s),1,fp);
    Decide if you want text or if you want binary. If you want text, write everything as text, and read it in as text and stuff it in your structure after you've read it. If you want binary, then fwrite is fine.
    Quote Originally Posted by tubby123 View Post
    Guys , so basically can you help me with a code that will take any integer (PART OF A STRUCTURE) and display it on the text doc.
    Code:
    fprintf( file, "%d", mystruct.myint );

    Quzah.
    Hope is the first step on the road to disappointment.

  3. #3
    Novice
    Join Date
    Jul 2009
    Posts
    568
    I would suggest having a pair of serialization functions.

    One that takes as an argument your structure and returns a string that contains structure field values (somehow delimited); another that takes as an argument a string, parses it, fills in a structure, while making the necessary conversions, and returns that.

    You can then serialize your structures, write them to human-readable files, and, when necessary, read the file back and fill in your structures.
    Disclaimer: This post shows my ignorance at the time of its making. I claim ownership of but not responsibility for all errors in it. Reference at your own peril.

  4. #4
    Registered User
    Join Date
    Jul 2011
    Posts
    18
    @quzah : hey, thanks
    1)
    fprintf( file, "%d", mystruct.myint );
    But i want to write the entire structure at once, rather than writing each instance using printf. Doesnt fwrite make matters easier cuz of this reason ?

    2)
    stuff it in your structure
    Exactly Sir, thats my question. How do i stuff into my structure.
    Because say i convert an int to a string, now how can i stuff the string back into the place which holds int.

    3)
    Congratulations! You've just discovered the difference between a binary and text file.
    Are u serious or sarcastic

    4)Sir, 1 last question
    Decide if you want text or if you want binary
    I dint get that, I do understand the difference between a text file and a binary file.
    But how does that depend on fwrite/fprintf ?
    Do you mean to say something like fwrite writes in binary whereas fprintf writes in text

    5)And yes, i DO want in text format.

  5. #5
    Registered User
    Join Date
    Jul 2011
    Posts
    18
    @msh, thank you sir, thats a really good solution. I'll do that. Do you mean to say, basically have another structure that has only string instances.
    Is this correct ?


    Code:
    struct s1
    {
     char* str1;
     char* str2;
     int num;
    }
    
    convert this to 
    
    struct s2
    {
     char* str1;
     char* str2;
     char* num;
    }
    Ok @quzah , so now it makes sense to me what u said.
    By stuff into your structure, you mean to say stuff into another structure ??? correct

  6. #6
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    No. I meant fscanf/fgets/whatever into a buffer, turn that into an int, and put the value in your structure. Why is it you think you need to do a single write instead of writing and reading multiple times? If you really want to write with a single write, sprintf into one big string and write that all at once.


    Quzah.
    Hope is the first step on the road to disappointment.

  7. #7
    Novice
    Join Date
    Jul 2009
    Posts
    568
    Quote Originally Posted by tubby123 View Post
    @msh, thank you sir, thats a really good solution. I'll do that. Do you mean to say, basically have another structure that has only string instances.
    Is this correct ?


    Code:
    struct s1
    {
     char* str1;
     char* str2;
     int num;
    }
    
    convert this to 
    
    struct s2
    {
     char* str1;
     char* str2;
     char* num;
    }
    Ok @quzah , so now it makes sense to me what u said.
    By stuff into your structure, you mean to say stuff into another structure ??? correct
    No. Note that I wrote "while making the necessary conversions". That means that after you have read a record back from file and split it based on whatever delimiter you choose while serializing; I expect you to, for example, convert fields that should be int's to int's by using atoi() function and then assign it to the appropriate field in the structure.

    There is no need for a second structure when implementing this solution.
    Disclaimer: This post shows my ignorance at the time of its making. I claim ownership of but not responsibility for all errors in it. Reference at your own peril.

  8. #8
    Novice
    Join Date
    Jul 2009
    Posts
    568
    This is what I was thinking of. Implementing the deserialization function for the provided prototype is left as an exercise for the OP.
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    #define MAX_RECORD_LEN 100
    
    typedef struct
    {
      char first_name[20];
      char last_name[20];
      int age;
      int height;
    } record;
    
    char* serialize(const record* p);
    record deserialize(char* line);   /* prototype for deserialization function */
    
    
    int main(void)
    {
      FILE* file = fopen("out.txt", "w");
      if (!file) {
        fprintf(stderr, "!! could not open output file\n");
        return 1;
      }
        
      record person = {"John", "Doe", 40, 180};
      char* sdata = serialize(&person);
      fprintf(file, "%s\n", sdata);
      
      fclose(file);
      free(sdata);
      return 0;
    }
    
    char* serialize(const record* p)
    {
      char* out = malloc(MAX_RECORD_LEN * sizeof(*out));
      if (!out) {
        fprintf(stderr, "!! could not allocate memory\n");
      } else {
        memset(out, '\0', MAX_RECORD_LEN);
        sprintf(out, "%s;%s;%d;%d", p->first_name, p->last_name, p->age, p->height);
      } 
      return out;
    }
    Disclaimer: This post shows my ignorance at the time of its making. I claim ownership of but not responsibility for all errors in it. Reference at your own peril.

  9. #9
    Registered User
    Join Date
    Jul 2011
    Posts
    18
    @quzah, msh : thanks a lot for all the help.
    I have 1 last question.
    Suppose s is my structure instance,
    Code:
    struct abc
    {
     char* name;
     int id;
    }s;
    And i use this to write mo my file.
    Code:
    fwrite(&s,sizeof(s),1,fp)
    Then can i use format specifiers to specify the format/spacing between the variable inside the structure (WHILE USING FWRITE AND NOT FPRINTF)

  10. #10
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,661
    I can see the same discussion and responses over here
    write structure to a file - C
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  11. #11
    Banned
    Join Date
    Aug 2010
    Location
    Ontario Canada
    Posts
    9,547
    Quote Originally Posted by tubby123 View Post
    @quzah, msh : thanks a lot for all the help.
    I have 1 last question.
    Suppose s is my structure instance,
    Code:
    struct abc
    {
     char* name;
     int id;
    }s;
    And i use this to write mo my file.
    Code:
    fwrite(&s,sizeof(s),1,fp)
    Then can i use format specifiers to specify the format/spacing between the variable inside the structure (WHILE USING FWRITE AND NOT FPRINTF)
    Oh my, this is very simple... If you use fwrite() to write a struct to a binary file, you need to use fread() to read the binary file back into a struct. You can then access the data from the struct instead of the file. No big deal...

    What you must change to make this work is the char* in your struct... it will need to be char name[30]; (or such) so that the data is actually stored in the struct and thus gets written to disk.
    Last edited by CommonTater; 07-02-2011 at 11:28 AM.

  12. #12
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Quote Originally Posted by tubby123 View Post
    Then can i use format specifiers to specify the format/spacing between the variable inside the structure (WHILE USING FWRITE AND NOT FPRINTF)
    I think this has already been strongly hinted at or explained in this thread, but if you do that, you will simply be printing the memory addresses in "name", and not the content it points to.

    And I have no idea what "format specifiers" you want to use with "fwrite and not printf" since fwrite does not use format specifiers.

    Using fwrite is only "easier" here, if by "easier" you mean: I did not have to code much and do not care whether what I am doing actually works -- because it won't.

    Quote Originally Posted by CommonTater View Post
    Oh my, this is very simple... If you use fwrite() to write a struct to a binary file, you need to use fread() to read the binary file back into a struct. You can then access the data from the struct instead of the file. No big deal...
    Unless, of course, you count the string a char* points to as "data". In that case, it's a big deal because that data will have been irretrievably lost.
    Last edited by MK27; 07-02-2011 at 11:23 AM.
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. write to file .. pointer to structure array
    By mad_muppet in forum C Programming
    Replies: 11
    Last Post: 05-07-2011, 05:33 AM
  2. How to write data from file to structure, This case is different.
    By TanzeelurRehman in forum C Programming
    Replies: 6
    Last Post: 12-22-2010, 11:34 PM
  3. How to write a function which returns a structure
    By MSF1981 in forum C Programming
    Replies: 2
    Last Post: 03-01-2009, 03:40 PM
  4. Replies: 5
    Last Post: 03-18-2006, 11:25 AM
  5. Structure Dynamic with File Write
    By k4z1nh0 in forum C Programming
    Replies: 1
    Last Post: 06-25-2005, 11:46 AM