Thread: Writing an array of struct to file

  1. #1
    Registered User
    Join Date
    Feb 2006
    Posts
    23

    Writing an array of struct to file

    Hi everybody,
    I want to write an array of struct to a file as I want that information to be loaded next time I run my program but I seem to have trouble writing an array of struct to a file... I can see that it is writing something to file but it is all jibberish... and I'm not sure why either.. here is my relevant code..
    my struct:
    Code:
    struct x{
      char name[100]; 
      int node; 
      short type; 
    };
    declaring my struct:
    Code:
    struct x HOME[1]; // Used to be 10 but set to 1 to see if I can write at least one element of an array
    function that writes to disk:
    Code:
    int closeDisk(struct x *d)
    {    
        if (fseek(my_disk, 0, SEEK_SET) != 0) 
    	{
    	    printf("Disk access error!\n");
    	    return 0; 
    	}
        fwrite((struct x*)d, sizeof(struct x), 1, my_disk);
    
        return 1;
    }
    when program starts up again, inside function that reads from file:
    Code:
    if ((my_disk = fopen(filename, "wb")) == NULL) // Create or open a new file
    	{
    	    printf("Error in opening the disk simulation file\n");
    	    exit(1);
    	}
        else
    	{
    		    if (fseek(my_disk, 0, SEEK_SET) != 0) 
    			{
    			    printf("Disk access error!\n");
    			    return 0; 
    			}
    		    fread((struct x*)d, sizeof(struct x), 1, my_disk);
    		    
                        // Test print to see what is read into struct
                        printf("%s\n%d\n",x[0].name,x[0].node);
    
    		   
    	}
    Does anyone see anything wrong? Any help would be greatly apprectiated...
    Thanks.

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    > fwrite((struct x*)d, sizeof(struct x), 1, my_disk)
    A pointless cast, and not checking the return result.

    > my_disk = fopen(filename, "wb")
    ...
    > fread((struct x*)d, sizeof(struct x), 1, my_disk)
    Trying to read from a file you just opened for writing.
    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.

  3. #3
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,057
    Try using "wb+" for the fopen mode.

    Code:
    fseek(my_disk, 0, SEEK_SET)
    There's an equivalent function called rewind() that does just that. You don't even need to rewind the file, when you open it it starts at the beginning.

    I don't know how you intend to read a structure from an empty file.
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

  4. #4
    Registered User
    Join Date
    Feb 2006
    Posts
    23
    Hi,
    so how I go about fixing my code though? (I removed the cast)
    I don't understand why you said "Trying to read from a file you just opened for writing." because when the program closes it writes the struct to file. That code you pointed out is at the beginning of the code when the program loads up again.. so technically there should be my struct data in there from last time the program was run... and doesn't 'wb' in fopen open the file for reading and writing?
    Thanks again.

  5. #5
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,057
    and doesn't 'wb' in fopen open the file for reading and writing?
    No, it doesn't, and that's what we're pointing out. You're thinking of mode "wb+" or "w+b".
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

  6. #6
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    > I don't understand why you said "Trying to read from a file you just opened for writing.
    How plain could it be?
    You open a file for WRITING with "wb" and 5 lines later you're trying to READ from the file.

    > and doesn't 'wb' in fopen open the file for reading and writing?
    See, most people read the manual page before passing random values to functions which just stop the compiler from moaning about syntax errors.
    Code:
    man fopen....
           w      Truncate file to zero length or create text file for writing.  The stream is positioned at
                  the beginning of the file.
    > so technically there should be my struct data in there from last time the program was run
    Only if your code contains a loop.
    If it quit back to the OS and you restarted it, then the answer is no it won't have any old data there.
    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.

  7. #7
    Registered User
    Join Date
    Feb 2006
    Posts
    23
    Hi,
    sorry about that.. I actually had it set to wb+ earlier but was playing around with it and didn't change it back.. my bad! I fixed that but I still do not anything meaningful from the file...
    i set name to "1212"
    and node to 5..
    when I exit the program and go back to the OS (Unix) I see that there is some stuff written to file... and some is legible...
    but when I run the program again nothing that I want is stored in the struct...
    this is what it prints out is inside the struct
    name: "ÿ;jÿ>mPÿ;"
    and node: 0
    What is going on?
    Thanks again.

  8. #8
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    Well since you're writing in binary mode, you're not going to see much by way of readable text.

    Use a hex editor, or this command line tool to view the binary file.
    Code:
    od -Ax -t x1z filename
    For example, setting node to 5 will result in 0x05 0x00 0x00 0x00 being stored in the file (somewhere)

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    struct x{
      char name[100];
      int node;
      short type;
    };
    
    int main ( ) {
      struct x foo = {
        "hello", 5, 123
      };
      FILE *fp = fopen("file.bin","wb");
      fwrite( &foo, sizeof foo, 1, fp );
      fclose( fp );
      return 0;
    }
    
    $ gcc bar.c
    $ ./a.out
    $ od -Ax -t x1z file.bin
    000000 68 65 6c 6c 6f 00 00 00 00 00 00 00 00 00 00 00  >hello...........<
    000010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  >................<
    *
    000060 00 00 00 00 05 00 00 00 7b 00 00 00              >........{...<
    00006c
    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.

  9. #9
    Registered User
    Join Date
    Feb 2006
    Posts
    23
    Hi,
    I've pinpointed my problem I think... It is like salem mentioned earlier.. I tested it out and if I write to the file and then read it while the program is running a get the results that I want. But if I close my program and then restart my program & try to read from the file at the beginning of the program there is weird data that goes into the struct...
    How do I fix this and what is happening to file when I close the program that data is changed next time I run the program?
    Thanks.

  10. #10
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    Post some more relevant code.
    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
    Registered User
    Join Date
    Feb 2006
    Posts
    23
    Hi!
    I actually fixed my code... by changing in fopen wb+ to rb+ it works!
    sorry about the trouble!

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 2
    Last Post: 07-11-2008, 07:39 AM
  2. gcc link external library
    By spank in forum C Programming
    Replies: 6
    Last Post: 08-08-2007, 03:44 PM
  3. C++ std routines
    By siavoshkc in forum C++ Programming
    Replies: 33
    Last Post: 07-28-2006, 12:13 AM
  4. File I/O problem for dynamically allocated struct array
    By veecee in forum C++ Programming
    Replies: 2
    Last Post: 05-05-2006, 09:28 PM
  5. Passing pointers between functions
    By heygirls_uk in forum C Programming
    Replies: 5
    Last Post: 01-09-2004, 06:58 PM