Thread: Saving information from a structure to a file

  1. #1
    Registered User
    Join Date
    Jan 2010
    Location
    Spanish Town, Jamaica, Jamaica
    Posts
    33

    Exclamation Saving information from a structure to a file

    No i've been googling for some time now and im yet to find a solution for this problem. I have a structure that has set variable that i need to store information to a file. Can someone tell me the easiest way to approach this?

  2. #2
    Registered User
    Join Date
    Oct 2008
    Location
    TX
    Posts
    2,059
    See the man pages of the block I/O functions: fread() and fwrite().

  3. #3
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Google "serialization".

    This may help:
    SourceForge.net: Serialization - cpwiki
    I wrote that, so it must be good.
    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

  4. #4
    [](){}(); manasij7479's Avatar
    Join Date
    Feb 2011
    Location
    *nullptr
    Posts
    2,657
    Quote Originally Posted by MK27 View Post
    I wrote that...
    I read that just now and noticed that it 'somewhat' avoids stream serialization and focuses on binary.
    Was that intentional?

    [Also...nice uncyclopedia link!]

  5. #5
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Quote Originally Posted by manasij7479 View Post
    I read that just now and noticed that it 'somewhat' avoids stream serialization and focuses on binary.
    Was that intentional?
    I think "stream vs. binary" is ambiguous, perhaps that is derived from the use of C++ operators? After all, there is such a thing as a binary or bit stream, but I presume you mean a "text stream".

    Anyway, yes it was intentional, but I just re-read it myself, lol, and you're right, it is slightly misleading that way, so I changed some of the text (eg, it now says, "Often serialized data files cannot be read as normal text in a file browser or editor, since the typed (ints, structs, etc) data need not be translated into strings. However, there are formal schemas for serialization (such as XML or JSON) that are based on such a translation; these are not much discussed here. "

    Also...nice uncyclopedia link!
    I am curious about the origin of that quote "Programmer (noun): An organism that can turn caffeine and alcohol into code". I'm sure it was actually laserlight
    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

  6. #6
    Banned
    Join Date
    Aug 2010
    Location
    Ontario Canada
    Posts
    9,547
    Quote Originally Posted by teensicle View Post
    No i've been googling for some time now and im yet to find a solution for this problem. I have a structure that has set variable that i need to store information to a file. Can someone tell me the easiest way to approach this?
    Can you post the definition of the struct please...

  7. #7
    [](){}(); manasij7479's Avatar
    Join Date
    Feb 2011
    Location
    *nullptr
    Posts
    2,657
    I presume you mean a "text stream"
    Yes....
    My point was that.. your block copying/dumping of memory could give interesting results when used with floating points.

  8. #8
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Quote Originally Posted by manasij7479 View Post
    Yes....
    My point was that.. your block copying/dumping of memory could give interesting results when used with floating points.
    Not if they are read in and out as floats, and the endianness is the same. As long as there are no pointers involved, you can write/transmit any C type out, including arrays and structs, arrays of structs, etc, and easily read them directly back in again (presuming you use the same types again).

    There is a potential complication with struct padding, of course.
    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

  9. #9
    [](){}(); manasij7479's Avatar
    Join Date
    Feb 2011
    Location
    *nullptr
    Posts
    2,657
    Quote Originally Posted by MK27 View Post
    As long as there are no pointers involved, you can write/transmit any C type out, including arrays and structs, arrays of structs, etc, and easily read them directly back in again (presuming you use the same types again).
    .Ok.

    @teensicle: Sorry for the minor Hijack !
    Now, if you haven't already solved the problem, post some code, as CommonTater suggested .

  10. #10
    Registered User
    Join Date
    Jan 2010
    Location
    Spanish Town, Jamaica, Jamaica
    Posts
    33

    1st try

    this is what i have i followed the cprogramming tutorial doesn't build though

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    
    typedef struct {
        char  p_name[10];
        int age;
    } records;
    
    int main (void)
    {
    
    
        FILE *fp;
        fp=fopen("test.bin", "wb");
    
            printf("Enter a name: \n");
                scanf("%s", &records.p_name);
    
            printf("Enter an age: \n");
                scanf("%d", &records.age);
    
        fwrite(name, sizeof(p_name),1, fp);
    
        fwrite(name, sizeof(age), 1, fp);
    
    }

  11. #11
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Here's a confusing thing about typedefs...this:

    Code:
    struct {
    } whatever;
    Defines a single instance of a struct called "whatever". But this:

    Code:
    typdef struct {
    } whatever;
    Defines a new type called "whatever", but not any instance of it. So with your code, you can either get rid of "typedef" or (preferably, IMO), declare an instance of type records:

    Code:
    records test;
    So now you have an instance of type records called "test". That means you have to change "records" to "test" in main(); "records" is the typename, "test" is the actual variable.

    In either case, you cannot refer to a member of a struct without the instance name, which you do in the two fwrite() calls. You need to use "records.age" (or "test.age") everytime.

    Finally, records.p_name in your original code is an array, so it counts as a pointer for scanf() -- you should not use & there. But you do need & with record.age in the fwrite, because the first arg to fwrite is a pointer.
    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

  12. #12
    Banned
    Join Date
    Aug 2010
    Location
    Ontario Canada
    Posts
    9,547
    @teensicle... The others are giving you very good advice about the creation and use of your struct, listen to them carefully.

    For my part in this I offer you the following demonstration program that uses a near identical struct... From my code word could be name and number could be age... so this is very like what you are probably trying to do. Pay paticular attention to how the records (structs) are written to and read from the data file... Copy and compile the program and run it to give yourself a demonstration of how it works... but don't even think about handing my code in as homework, it's been posted several times in a couple of different places so you'll just get yourself in trouble for cheating. However, if you follow the techniques used, you can finish your program.

    Code:
    //random access file demo
    #include <stdlib.h>
    #include <stdio.h>
    #include <time.h>
    #include <ctype.h>
    #include <string.h>
    
    #define FNAME "random.dat"
    
    // test data struct
    struct t_Record
      { int number;
        char word[16]; }
      Record;
    
    
    
    ///////////////////////////////////////////////////////
    // Random Access File Handlers
    //
    
    // open or create the file
    FILE *FileOpen(char* Filename)
      { FILE* pFile;
        pFile = fopen(Filename,"rb+");
        if (!pFile)
          pFile = fopen(Filename,"wb+");
        return pFile; }
    
    
    // Write a record to the file
    int WriteRecord(FILE *File, int RecNum)
      { if( fseek(File, RecNum * sizeof(Record), SEEK_SET) == 0 )
          if ( fwrite(&Record,sizeof(Record),1,File) )
            return 1;
        return 0; }
    
    
    // read a record from the file
    int ReadRecord(FILE *File, int RecNum)
      { if( fseek(File, RecNum * sizeof(Record), SEEK_SET) == 0 )
          if ( fread(&Record,sizeof(Record),1,File) )
            return 1;
        return 0; }
    
    
    // add a new record to the file
    int AddRecord(FILE *File)
      { fseek(File,0,SEEK_END);
        fwrite(&Record,sizeof(Record),1,File);
        return (ftell(File) / sizeof(Record)) - 1; }
    
    
    
    //////////////////////////////////////////////////////////////
    // View a Record
    //
    
    int ViewRecord (FILE *File, int RecNum)
      { if (! ReadRecord(File,RecNum))
          { printf("Invalid record\n"); 
            return -1; }
        printf("-----\n");
        printf("Record        : %d\n",RecNum);
        printf("Number Value  : %d\n",Record.number);
        printf("Word Value    : %s\n",Record.word);
        printf("-----\n");  
        return RecNum; }
    
    
    
    //////////////////////////////////////////////////////////////
    // Add a new record
    //
    
    int AddNewData(FILE *File)
      { memset(&Record,0,sizeof(Record));
        printf("\nEnter a number : ");
        scanf("%d", &Record.number);
        printf("Enter a word : ");
        scanf(" %s",Record.word);
        return AddRecord(File); }
    
    
    
    //////////////////////////////////////////////////////////////
    // Edit a record
    //
    
    int EditRecord(FILE *File, int RecNum)
      { if (! ReadRecord(File,RecNum))
          { printf("Invalid record\n");  
            return -1; }
        printf("\n-----\n");
        printf("Record        : %d\n",RecNum);
        printf("Number Value  : %d\n",Record.number);
        printf("Word Value    : %s\n",Record.word);
        printf("-----\n");  
        
        do
          { while(getchar() != '\n');
            printf("Change Values: Number, Word or Save (N, W or S) ? ");
            switch (toupper(getchar()))
              { case 'N' :
                  printf("\nEnter new number : ");
                  scanf("%d",&Record.number);
                  break;
                case 'W' : 
                  printf("Enter new word : ");
                  scanf(" %15s", Record.word);
                  break;
                case 'S' :
                  if (WriteRecord(File,RecNum))
                    printf("\nRecord #%d updated\n",RecNum);
                  return RecNum; } }
        while(1);
        return -1; }
    
    
    ////////////////////////////////////////////////////////////////
    // List records
    // 
    
    void ListRecords(FILE *File )
      { int i = 0;
        printf("\nRecord     Number\tWord\n\n");
        while (ReadRecord(File,i))
          { printf("%3d%16d\t%s\n",i,Record.number,Record.word); 
            i++; }
        printf("\n\n"); }
    
    
    
    ////////////////////////////////////////////////////////
    // this is for demonstration purposes only
    // you would not do this in a real program
    void InitFile(FILE* File)
     { int x, y;
       memset(&Record,sizeof(Record),0);
       for (x = 0; x < 10; x++)
          { Record.number = rand();
            for (y = 0; y < ((Record.number % 15) + 1); y++)
              Record.word[y] = (rand() % 26) + 'a';
            Record.word[y] = 0;
            if (! WriteRecord(File,x))
              printf("Oh drat!");  } }
     
    
    
    //////////////////////////////////////////////////////////
    // program mains
    //
    int main (void)
      { int Rec = 0; // record number
        FILE *File;
    
        srand(time(NULL));
    
        File = FileOpen(FNAME); 
        if (!File)
          { printf("Curses foiled again!\n\n");
            exit(-1); }
    
        printf("Random Access File Demonstration\n\n");
     
        do
          { printf("Menu : Dummy, Add, Edit, View, List, Quit (D, A, E, V, L or Q) : ");
            switch(toupper(getchar()))
              { case 'D' :
                  printf("Creating dummy file of 10 entries\n");
                  InitFile(File);
                  break;
                case 'A' :
                  Rec = AddNewData(File);
                  printf("Record #%d Added\n\n", Rec);
                  break;              
                case 'E' :
                  printf("\nRecord number (-1 Cancels): ");
                  scanf("%d",&Rec);
                  if (Rec > -1)
                    EditRecord(File,Rec);
                  break;
                case 'V' :
                  printf("\nRecord number (-1 Cancels): ");
                  scanf("%d",&Rec);
                  if (Rec > -1)
                    ViewRecord(File,Rec);
                  break;
                case 'L' :
                  ListRecords(File);
                  break;
                case 'Q' :
                  fclose(File);
                  return 0; } 
                  
             while(getchar() != '\n'); }
        while (1); 
        return 0; }
    Last edited by CommonTater; 11-13-2011 at 01:13 PM.

  13. #13
    Registered User
    Join Date
    Jan 2010
    Location
    Spanish Town, Jamaica, Jamaica
    Posts
    33
    @MK27 and @Commontater i really get what your saying and will modify the code!

  14. #14
    Registered User
    Join Date
    Jan 2010
    Location
    Spanish Town, Jamaica, Jamaica
    Posts
    33
    @Commontater and @MK27 dudes you guys rock!

  15. #15
    Banned
    Join Date
    Aug 2010
    Location
    Ontario Canada
    Posts
    9,547
    Quote Originally Posted by teensicle View Post
    @MK27 and @Commontater i really get what your saying and will modify the code!
    BZZZZT... wrong answer!

    Don't just re-edit my code... spend the time to learn how it actually works and WRITE YOUR OWN CODE.

    You don't learn a blessed thing by copying from others.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 9
    Last Post: 08-09-2008, 10:47 AM
  2. Saving structure to a file
    By eth0 in forum C++ Programming
    Replies: 20
    Last Post: 01-07-2004, 04:26 AM
  3. saving structure with fwrite
    By GaPe in forum C Programming
    Replies: 3
    Last Post: 02-26-2003, 11:20 AM
  4. saving/reading information to/from a .txt using C++..
    By Unregistered in forum C++ Programming
    Replies: 3
    Last Post: 08-31-2002, 01:23 PM
  5. Saving information
    By bluehead in forum C++ Programming
    Replies: 5
    Last Post: 01-08-2002, 06:15 PM