Thread: Printing a list of structures from a binary file

  1. #1
    Registered User
    Join Date
    May 2003
    Posts
    6

    Printing a list of structures from a binary file

    Hello, first post here. Be gentle. Anyway i am trying to read in and print data structures from a binary file. Initially i tried it this way

    Code:
    while(!feof(fp))
    {
            if(fread(&data, sizeof(DATA), 1, fp) != 1)
            {
                    fprintf(stdout, "ERROR: file read\n");
                    exit(1); 
            }
                    
            printrecord(data);
                   
    }
    Basically this didnt really work, in the sense that it would do what i wanted it to do but at the last record it would trigger the ERROR: file read and then print out the last record again. After doing some searches and reading some of your fine posts i gathered that this was because of my misguided use of !feof(fp) as a stop condition. So i reworked it and came up with:

    Code:
    while(fread(&data, sizeof(DATA), 1, fp) != NULL)
    {
          printrecord(data);
    }
    While this one works (as far as i tested it) in the sense that it prints out all the records and then stops after the last record without any errors, it is more or less devoid of any error checking.
    Would you please post your thoughts and let me know the generally accepted method for accomplishing this?

    Thank you,
    -Emrys

  2. #2
    Confused Magos's Avatar
    Join Date
    Sep 2001
    Location
    Sweden
    Posts
    3,145
    Perhaps not the answer you're looking for, but I usually store an integer at the beginning of the file telling how many records there are then read the data that many times:
    Code:
    DATA* Data;
    
    FILE* File;
    int NrOfRecords;
    
    File = fopen("MyFile.dat", "rb");
    if(File != NULL)
    {
       //Read the nr of records
       fread(&NrOfRecords, sizeof(int), 1, File);
    
       //Allocate memory for the data
       Data = malloc(NrOfRecords * sizeof(DATA));
       if(Data == NULL)
       {
          fclose(File);
          return;
       }
    
       //Read the records
       fread(Data, sizeof(DATA), NrOfRecords, File);
    
       fclose(File);
    }
    Make sure you've allocated memory for Data.

    EDIT: Memory allocation added.
    Last edited by Magos; 05-12-2003 at 03:18 AM.
    MagosX.com

    Give a man a fish and you feed him for a day.
    Teach a man to fish and you feed him for a lifetime.

  3. #3
    Registered User
    Join Date
    May 2003
    Posts
    6
    Well, i havent allocated any memory for data, nor have i kept a record of how many entries there are in the binary file. I kept expecting to need some reference as to how many entries there were, but i kept putting it off and in the end the program does what is needed (of course thats in a closed environment). However at this stage i see no need to keep a record of how many entries because every function that accesses the binary file just overwrites the structure variable (data). There is only one entry in memory at any one time... Is this bad? Or rather poor coding practice?

  4. #4
    Confused Magos's Avatar
    Join Date
    Sep 2001
    Location
    Sweden
    Posts
    3,145
    Is this bad? Or rather poor coding practice?
    It depends on your intentions. I didn't notice you only stored one DATA at a time, thus the need to read only 1 record at a time using some kind of loop instead of what I did and read them all into an array (note: Data in my example above is an array of DATA, not a single variable).

    I'd rather say it's good coding practise since it takes up less memory, and unless you need to have them all in memory at the same time that would probably be the best solution.

    If you store a record count in the beginning and want to read only 1 at a time:
    Code:
    FILE* File;
    int NrOfRecords;
    DATA Data;
    
    File = fopen("MyFile.dat", "rb");
    if(File != NULL)
    {
       //Read the nr of records
       fread(&NrOfRecords, sizeof(int), 1, File);
    
       //Read the records
       for(int i=0; i<NrOfRecords; i++)
       {
          fread(&Data, sizeof(DATA), 1, File);
    
          //Do something with the data
       }
    
       fclose(File);
    }
    MagosX.com

    Give a man a fish and you feed him for a day.
    Teach a man to fish and you feed him for a lifetime.

  5. #5
    Registered User
    Join Date
    May 2003
    Posts
    6
    Aye, well the reason i kept putting off keeping a record of entries was that in the end i will not know how many entries there will be as another part of that program will be adding entries to the file... anyway thanks for your input. Also any thoughts as to my original question about my method for testing for end of file that has no error checking?

    Thanks
    -emrys

  6. #6
    Registered User
    Join Date
    May 2003
    Posts
    6
    I'm still curious as to whether using an fread statment is appropriote for a stop condition. the compiler gives me a warning saying "comparison between pointer and integer". the whole thing comiles and works great, but i still want to know if that is a good way of doing it?

    Thanks
    -emrys

  7. #7
    Confused Magos's Avatar
    Join Date
    Sep 2001
    Location
    Sweden
    Posts
    3,145
    Syntax

    #include <stdio.h>
    size_t fread(void *ptr, size_t size, size_t n, FILE *stream);

    Description

    Reads data from a stream.
    fread reads n items of data each of length size bytes from the given input stream into a block pointed to by ptr.
    The total number of bytes read is (n * size).

    Return Value

    On success fread returns the number of items (not bytes) actually read.
    On end-of-file or error it returns a short count (possibly 0).

    Borland C++ 5.0 Programmer's Guide
    You compare that return value with NULL (why do that?) thus getting a compare-int-with-pointer warning. Since NULL is defined as 0 it still gives the correct result.
    MagosX.com

    Give a man a fish and you feed him for a day.
    Teach a man to fish and you feed him for a lifetime.

  8. #8
    Registered User
    Join Date
    May 2003
    Posts
    6
    Okay, i think i got it. Thanks for all your help.

    -Emrys

  9. #9
    Registered User Vber's Avatar
    Join Date
    Nov 2002
    Posts
    807
    I don't think anyone told you but
    >>while(!feof(fp))
    is a big no-no, you should try looking at the FAQ to see "why".

  10. #10
    Registered User
    Join Date
    May 2003
    Posts
    6
    If you read my first post in full you would see that i did not use while(!feof()) and why. But thank you for your response.

    -Emrys

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. gcc link external library
    By spank in forum C Programming
    Replies: 6
    Last Post: 08-08-2007, 03:44 PM
  2. singly linked circular list
    By DarkDot in forum C++ Programming
    Replies: 0
    Last Post: 04-24-2007, 08:55 PM
  3. Dikumud
    By maxorator in forum C++ Programming
    Replies: 1
    Last Post: 10-01-2005, 06:39 AM
  4. Unknown Memory Leak in Init() Function
    By CodeHacker in forum Windows Programming
    Replies: 3
    Last Post: 07-09-2004, 09:54 AM
  5. How can I traverse a huffman tree
    By carrja99 in forum C++ Programming
    Replies: 3
    Last Post: 04-28-2003, 05:46 PM