Thread: Reading structures

  1. #16

  2. #17
    End Of Line Hammer's Avatar
    Join Date
    Apr 2002
    Posts
    6,231
    Here's a sample program that reads and writes struct to a file. It does various, so watch for the comments in the source to see what's happening. Hope you can learn something from it, and get your code to do what you want.
    Code:
    #include <stdio.h>
    #include <string.h>
    
    int main(void)
    {
        FILE *fp;
        int i;
    
        /*
         * This defines the struct and declares an array of size 6, plus 2 single struct variables
         */
        struct myData
        {
            int i;
            char name[10];
        };
        
        struct myData   bufStruct, 
                        oneStruct, 
                        aryStruct[6] = {{0,{0}}};
        
        /* 
         * Here we fill only the first 5 array elements with aryStruct
         * The 6th element will be populated by reading from the file.
         */
        strcpy(aryStruct[0].name, "name0");
        strcpy(aryStruct[1].name, "name1");
        strcpy(aryStruct[2].name, "name2");
        strcpy(aryStruct[3].name, "name3");
        strcpy(aryStruct[4].name, "name4");
        
        for (i = 0; i < 5; i++)
        {
            aryStruct[i].i = i;
        }
        
        /* 
         * open the file, and write 5 array elements to it
         */
        if ((fp = fopen("myfile.bin", "w+b")) == NULL)
        {
            return 1;
        }
        
        for (i = 0; i < 5; i++)
        {
            fwrite (&aryStruct[i], sizeof(struct myData),1, fp);
        }
        
        /*
         * Now seek to the beginning of the last struct in the file.
         * This is done by seeking backwards from the end, by the 
         * sizeof struct myData
         */
        fseek(fp, sizeof(struct myData) * -1, SEEK_END);
        
        /*
         * Now read in the last struct from the file into array element number 6
         */
        fread(&aryStruct[5], sizeof(struct myData),1, fp);
        
        /*
         * Now print all 6 array elements to prove the aryStruct is good.
         * You will note that the last 2 elements have the same data in them.
         */
         
        for (i = 0; i < 6; i++)
        {
            printf ("%d, %s\n", aryStruct[i].i, aryStruct[i].name);
        }
        
        /*
         * Now as a further exercise, read through the file from the beginning,
         * getting one struct at a time into a single buffer, and counting as we go.
         * When we get to EOF, we have the last struct, and we know how many were in the file.
         */
        
        rewind (fp);
        
        for (i = 0; fread(&bufStruct, sizeof(struct myData),1, fp) == 1; i++)
        {
            oneStruct = bufStruct;
        }
        
        printf ("There are %d readable structs in the file\n", i);
        printf ("The last struct's aryStruct: %d, %s\n", oneStruct.i, oneStruct.name);
        
        fclose(fp);    
        return 0;
    }
    When all else fails, read the instructions.
    If you're posting code, use code tags: [code] /* insert code here */ [/code]

  3. #18
    Registered User
    Join Date
    Aug 2002
    Posts
    109

    Ummm

    Thanks hammer for that but, Could it be made into to seperate programs one which writes the struc's and another which reads them. Its important that the program dosen't know how many strucs there are because in an address book you don't know how many contacts the user is going to have in his/hers address book.

    Thanks
    OS:- XP
    Compiler:- MSVC++ 6 or DJGPP or Dev-c++ (Mingw)

  4. #19
    End Of Line Hammer's Avatar
    Join Date
    Apr 2002
    Posts
    6,231

    Re: Ummm

    Originally posted by Granger9
    Thanks hammer for that but, Could it be made into to seperate programs one which writes the struc's and another which reads them. Its important that the program dosen't know how many strucs there are because in an address book you don't know how many contacts the user is going to have in his/hers address book.

    Thanks
    Yes, of course. Just split up my code into the two programs. One will need to fopen() with read and the other with write.
    When all else fails, read the instructions.
    If you're posting code, use code tags: [code] /* insert code here */ [/code]

  5. #20
    Registered User
    Join Date
    Aug 2002
    Posts
    109

    I tryed

    I tryed spilting the code into two but it didn't work the output from the program was;

    0,
    0,
    0,
    0,
    0,
    0,

    this is the code for the second program which produced the output above:
    Code:
    #include <stdio.h>
    #include <string.h>
    
    int main(void)
    {
        FILE *fp;
        int i;
    
        /*
         * This defines the struct and declares an array of size 6, plus 2 single struct variables
         */
        struct myData
        {
            int i;
            char name[10];
        };
        
        struct myData   bufStruct, 
                        oneStruct, 
                        aryStruct[6] = {{0,{0}}};
                        
                        
        if ((fp = fopen("myfile.bin", "w+b")) == NULL)
        {
            return 1;
        }
    
         /*
         * Now seek to the beginning of the last struct in the file.
         * This is done by seeking backwards from the end, by the 
         * sizeof struct myData
         */
        fseek(fp, sizeof(struct myData) * -1, SEEK_END);
        
        /*
         * Now read in the last struct from the file into array element number 6
         */
        fread(&aryStruct[5], sizeof(struct myData),1, fp);
        
        
        
        fseek(fp, sizeof(struct myData) *0, SEEK_SET);
        /*
         * Now print all 6 array elements to prove the aryStruct is good.
         * You will note that the last 2 elements have the same data in them.
         */
         
        for (i = 0; i < 6; i++)
        {
            printf ("%d, %s\n", aryStruct[i].i, aryStruct[i].name);
        }
        
        return 0;
    }
    OS:- XP
    Compiler:- MSVC++ 6 or DJGPP or Dev-c++ (Mingw)

  6. #21
    End Of Line Hammer's Avatar
    Join Date
    Apr 2002
    Posts
    6,231
    I presume the code you posted is supposed to open the file, and read from it?

    >fopen("myfile.bin", "w+b"))
    This will open the file, and truncate it. Basically meaning that you delete the contents before you start! Try mode "rb".

    >Its important that the program dosen't know how many strucs there are
    Another thing to note here, if you want to load all structs from the file into memory, you'll need an array, list, tree or something. If you use an array, it'll be a fixed size, and will therefore not be able to load a indefinate number. A list or tree would be better, or anything that implements dynamic memory allocation.

    Failing that, hard code an array size, and when looping through the input file, make sure you don't read more than the max number allowed by your array.
    When all else fails, read the instructions.
    If you're posting code, use code tags: [code] /* insert code here */ [/code]

  7. #22
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,708
    There is no "append" mode for binary. Use this:



    Code:
    
    FILE * bopen(char file[], char mode[])
     {
       bool writing = false;
     
       if( strstr(mode, "w") )
        { 
          writing = true; 
        }
    
       FILE *handle = fopen(file, (writing == true ) ? "wb" : "rb");
      
       if(writing)fseek( handle, 0L, SEEK_END)
       
       return handle;
     }
    ie: FILE *fp = bopen("file.dat", "w");

    Or even:

    Code:
    FILE * reader( char file[] )
     {
       FILE *handle = fopen(file, "rb");
    
       return handle;
     }
    
    
    
    FILE * writer( char file[] )
     {
       FILE *handle = fopen(file, "wb");
    
       fseek(handle, )L, SEEK_END);
    
       return handle;
     }

    I actually like these better, since they are more readable:

    FILE *fp = writer( "file.dat" );




    Anyway, GET RID of the goto's at some convenient point. A big "no"

    And you have something like 50 variables named "a". Perhaps you could give them more unique names?

    Just a suggestion...
    Code:
    #include <cmath>
    #include <complex>
    bool euler_flip(bool value)
    {
        return std::pow
        (
            std::complex<float>(std::exp(1.0)), 
            std::complex<float>(0, 1) 
            * std::complex<float>(std::atan(1.0)
            *(1 << (value + 2)))
        ).real() < 0;
    }

  8. #23
    End Of Line Hammer's Avatar
    Join Date
    Apr 2002
    Posts
    6,231
    Originally posted by Sebastiani
    There is no "append" mode for binary.
    Hmm, it says this in my ref docs:
    r
    open file for reading
    w
    create file for writing, or truncate to zero length
    a
    append: open text file or create for writing at end-of-file
    r+
    open file for update (reading and/or writing); use default file translation
    w+
    create file for update, or truncate to zero length; use default file translation
    a+
    append; open file or create for update, writing at end-of-file; use default file translation

    The letter b may be added to any of the above sequences in the second or third position to indicate that the file is (or must be) a binary file (an ANSI requirement for portability to systems that make a distinction between text and binary files). Under QNX, there is no difference between text files and binary files.
    When all else fails, read the instructions.
    If you're posting code, use code tags: [code] /* insert code here */ [/code]

  9. #24
    Visionary Philosopher Sayeh's Avatar
    Join Date
    Aug 2002
    Posts
    212
    Without all the hoopla,

    The program dosen't know how many contacts are saved so it can't open them all.
    It's not going to know that unless you store that number in the file along with the data. Otherwise, if the file is _only_ same-size structures (all the records are the same), then you can do this:

    Code:
    records = filesize / sizeof(struct);              /* pseudocode */
    that will return you the number of structure in the file.
    It is not the spoon that bends, it is you who bends around the spoon.

  10. #25
    Registered User
    Join Date
    Aug 2002
    Posts
    109

    Cant you do it this way

    Hi all

    I have figured out how to do what I was doing. It was because of Hammer defintions of all the read and write types now that I put a wb & rb it works!

    This is what I was trying to achive

    The write program
    Code:
    /*-The write program-*/
    #include <stdio.h>
    
    struct rec
    {
        int the;
        int x;
    }r;
    
    FILE *f;
    int i,q;
    
    int main()
    {
    r.x=0;
    printf("how many strucs: ");
    scanf("%d", &i);
    
    
    f=fopen("open_read","wb");
        if (!f)
            return 1;
    for (q=1;q<=i; q++)
    {
    r.the=q;
    r.x++;
    fwrite(&r,sizeof(struct rec),1,f);
    }
    fclose(f);
    
    return 0;
    }
    The read program
    Code:
    /*-The read program-*/
    #include <stdio.h>
    
    struct rec
    {
        int the;
        int x;
    }r;
    
    int main()
    {
        int i,j;
        FILE *f;
    
    
    
    f=fopen("open_read","rb");
        if (!f)
            return 1;
        fseek(f, sizeof(struct rec) * -1, SEEK_END);
        fread(&r, sizeof(struct rec),1, f);
        j=r.x;
        fseek(f, sizeof(struct rec) *0, SEEK_SET);
        
        for (i=1;i<=j; i++)
        {
            fread(&r,sizeof(struct rec),1,f);
            printf("%d\n",r.the);
            printf("this %d\n",r.x);        
        }
            
          
        fclose(f);
    
        
        
    return 0;
    }
    Simple problem but its taken me three days to work out!

    If anyone has any suggestions on how to make this better please suggest it.

    Now I have solved that little problem I look like this Thank you everyone.

    Oww my mouth hurts I'm think i'm going to stop smiling so much and simle like this thats better
    OS:- XP
    Compiler:- MSVC++ 6 or DJGPP or Dev-c++ (Mingw)

  11. #26
    Registered User
    Join Date
    Aug 2002
    Posts
    109

    I have one slight problem

    With my code everytime you write somthing to it it deletes what was previously in it. Can someone please tell how to make it so it just adds the stuff on the end instead of overwriting the file


    Thanks
    OS:- XP
    Compiler:- MSVC++ 6 or DJGPP or Dev-c++ (Mingw)

  12. #27
    Registered User
    Join Date
    Aug 2002
    Posts
    109
    I have done it I had to add a mode of ab to the read and it seems to work fine
    OS:- XP
    Compiler:- MSVC++ 6 or DJGPP or Dev-c++ (Mingw)

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 2
    Last Post: 07-11-2008, 07:39 AM
  2. Structures within Structures
    By Misko82 in forum C Programming
    Replies: 2
    Last Post: 08-27-2007, 12:25 AM
  3. Structures, passing array of structures to function
    By saahmed in forum C Programming
    Replies: 10
    Last Post: 04-05-2006, 11:06 PM
  4. Replies: 2
    Last Post: 06-16-2005, 10:03 AM
  5. Structures, and pointers to structures
    By iloveitaly in forum C Programming
    Replies: 4
    Last Post: 03-30-2005, 06:31 PM