Thread: fwriting and freading binary (structs)

  1. #1
    Registered User
    Join Date
    Jan 2019
    Posts
    13

    fwriting and freading binary (structs)

    Here is my struct:

    Code:
    struct location {
     int houseNumber;
     char streetName[STRING_BUF];
     char city[STRING_BUF];
     char state[STATE_BUF];
     int zip;
    };
    
    struct person {
     char nameFirst[STRING_BUF];
     char nameLast[STRING_BUF];
     char number[STRING_BUF];
     struct location address;
     struct person *next;
    } entry[100];
    
    typedef struct person PERSON;
    typedef PERSON *PERSON_PTR;

    And here is the fwrite:

    Code:
    void write_to_disk (PERSON_PTR first)
    {
     PERSON_PTR cur_ptr;
     cur_ptr = first;
    
     if ( (fp = fopen(filename, "wb") ) == NULL )
     {
      fprintf(stderr, "Error opening file %s\n", filename);
      exit(1);
     }
    
     while (cur_ptr != NULL)
     {
      if ( fwrite(cur_ptr, sizeof(PERSON), 1, fp) != 1)
      {
       fprintf(stderr, "Error writing to %s.", filename);
       exit(1);
      }
      cur_ptr = cur_ptr->next;
     }
    
     fclose(fp);
    }
    But now how to read the file? I can post my attempt but wanted to keep it streamline. I actually don't even know if I'm writing to the file correctly.

  2. #2
    Programming Wraith GReaper's Avatar
    Join Date
    Apr 2009
    Location
    Greece
    Posts
    2,728
    fread() take the same arguments, and transfers data from the file to memory. Try it. Don't forget to open the file with "rb" though.

    Also, just a bit of advice, don't typedef pointers. Obscuring a pointer is discouraged because it can be a source of confusion and potential errors.
    Devoted my life to programming...

  3. #3
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    37,534
    Beware that your person->next member will be meaningless when you fread() it back in.
    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.

  4. #4
    Registered User
    Join Date
    Feb 2019
    Posts
    550
    You could do something like this:
    Code:
    int write_persons_list( char *filename, PERSON_PTR pptr )
    {
      PERSON_PTR p;
      FILE *f;
      uint32_t count;
      
      if ( ! ( f = fopen( filename "w" ) ) )
        return 0;
    
      count = 0;
      if ( fwrite( &count, sizeof count, 1, f ) != 1 )
      {
    error:
        fclose( f );
    
        // delete the file in case of error!
        unlink( filename );
    
        return 0;
      }
    
      p = pptr;
      while ( p )
      {
        // don't write p->next!
        if ( fwrite( p, offsetof(PERSON,next), 1, f ) != 1 )
          goto error;
    
        p = p->next;
        count++;
      }
    
      // Write the number of elements...
      fseek( f, 0, SEEK_SET );
      if ( fwrite( &count, sizeof count, 1 f ) != 1 )
        goto error;
    
      fclose( f );
    
      return 1;
    }
    
    // Example call:
    //
    //  PERSON_PTR *plist;
    //  if ( ! read_persons_list( "./list.bin", &plist ) ) { ... error handling... }
    int read_persons_list( char *filename, PERSON_PTR *pp )
    {
      PERSON *p;
      FILE *f;
      uint32_t count;
    
      if ( ! ( f = fopen( filename, "r" ) ) )
        return 0;
    
      if ( fread( &count, sizeof count, 1, f ) != 1 )
      {
    error:
        fclose( f );
        return 0;
      }
    
      if ( count == 0 )
        goto error;
    
      if ( ! ( *pp = malloc( count * sizeof( PERSON ) ) )
        goto error;
    
      p = *pp;
      while ( count-- )
      {
        // don't read p->next!
        if ( fread( p, offsetof( PERSON, next ), 1, f ) != 1 )
        {
          free( *pp );
          goto error;
        }
    
        p->next = ++p;
      }
    
      // the last one must be NULL.
      (p - 1)->next = NULL;
    
      fclose( f );
    
      return 1;
    }

  5. #5
    Registered User
    Join Date
    Jan 2019
    Posts
    13
    Thanks all. I wrote this read attempt before viewing your advice. I don't expect you to go through it. I will look over your code, @flp1969, as mine errors out during fread. I am obviously a beginner. Thanks for taking the time.

    Code:
    PERSON_PTR read_file (PERSON_PTR first)
    {
     PERSON_PTR cur_ptr;
     cur_ptr = first;
    
    if ( (fp = fopen(filename, "r+b") ) == NULL )
     {
      fprintf(stderr, "Error opening file %s\n", filename);
      exit(1);
     }
    
     while (!feof(fp))
     {
      if ( fread(cur_ptr, sizeof(PERSON), 1, fp) != 1)
      {
       fprintf(stderr, "Error reading from %s.", filename);
       exit(1);
      }
    strcpy(entry[i].nameFirst, cur_ptr->nameFirst);
      strcpy(entry[i].nameLast, cur_ptr->nameLast);
      strcpy(entry[i].number, cur_ptr->number);
      entry[i].address.houseNumber = cur_ptr->address.houseNumber;
      strcpy(entry[i].address.streetName, cur_ptr->address.streetName);
      strcpy(entry[i].address.city, cur_ptr->address.city);
      strcpy(entry[i].address.state, cur_ptr->address.state);
      entry[i].address.zip = cur_ptr->address.zip;
    
      first = add_to_list (entry[i], first);
      i++;
     }
     fclose(fp);
    
     return (first);
    }

  6. #6
    TEIAM - problem solved
    Join Date
    Apr 2012
    Location
    Melbourne Australia
    Posts
    1,859
    Code:
    while (!feof(fp))
    This is a bug - Why it's bad to use feof() to control a loop - Cprogramming.com

    ... and also this faq: Question 12.2
    Fact - Beethoven wrote his first symphony in C

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Binary File Structs
    By csharp100 in forum C Programming
    Replies: 9
    Last Post: 04-12-2012, 02:44 PM
  2. freading from multiple opened files
    By TeQno in forum C Programming
    Replies: 1
    Last Post: 05-23-2003, 07:03 AM
  3. Dilema - Fwriting
    By MethodMan in forum C Programming
    Replies: 1
    Last Post: 03-30-2003, 11:10 AM
  4. reading from structs in a binary file
    By Unregistered in forum C Programming
    Replies: 4
    Last Post: 12-21-2001, 10:52 AM
  5. Difficulty freading an array of structures
    By Sebastiani in forum C Programming
    Replies: 2
    Last Post: 09-12-2001, 01:08 PM

Tags for this Thread