fwrite & fread problems

Member
Posts: 21
Joined: 2009.05
Post: #1
Greetings all,
Yes, it is me again. >< I hope you know you all are my last resort... so, even though I seem to bug you a lot, I do a lot of research first.

This post concern my text rpg, again. I am trying to resolve a problem I have with my load and save system. First off, everything works just fine, and has been working for the last week or so, that is, until I added a delete file function.

Within my game, you can start up to four games. Each game file name is saved within my file: saves - which is created if it does not already exist. When you create a new game, it creates a new file with your game name. So, my EraseGame() function asks you which file you wish to delete. You make your selection, it takes your input and removes the correct file, then sets the name that is stored in 'saves' to --( U n u s e d )--. The variable that holds the names that is stored in 'saves' is: fileName[ 5 ][ 32 ];

My problem is, when the program reads from the file after you delete a file, it removes the first three characters from every game name. So, all my --( U n u s e d )-- become U n u s e d )--. My game name: Achithyn, becomes ithyn.

Here's the code I use to remove the game file, and rename the fileName:

Code:
strcpy( fileName[ playerInt ], "--( U n u s e d )--" );

if ( ( fp = fopen( "saves", "wb" ) ) == NULL )
{
    printf( "\t[ Cannot open file. ]\n" );
    exit( 1 );
}
                    
fwrite( fileName, sizeof( fileName ), 5, fp );
                
fclose( fp );

This is the code that reads the content in 'saves'

Code:
if ( ( fp = fopen( "saves", "rb" ) ) == NULL )
    if ( ( fp = fopen( "saves", "wb+" ) ) == NULL ) // -If no file is present, create one
    {
        printf( "Cannot open file." );
        exit( 1 );
    }
            
fread( &playNum, sizeof( playNum ), 1, fp ); // Checks to see if this is the first time the game has run
fread( fileName, sizeof( fileName ), 5, fp );
            
fclose( fp );

And that's all I have. I hope you can help me here... been playing with this problem since last night. >< Thank you for your help and time! BTW, this is programmed with C99.

~Achi
Quote this message in a reply
Sage
Posts: 1,403
Joined: 2005.07
Post: #2
shouldnt you do
fwrite( fileName[ playerInt ], sizeof( fileName ), 5, fp );
instead of
fwrite( fileName, sizeof( fileName ), 5, fp );
?

Sir, e^iπ + 1 = 0, hence God exists; reply!
Quote this message in a reply
Member
Posts: 21
Joined: 2009.05
Post: #3
Though wouldn't that practically do the same thing? One stores all the values of fileName, the other updates one. I admit, yours would likely be better, though I doubt it would solve the problem. I'll go ahead and give it a try anyway... though I think I tried that... hmmm.

This is what I get now:
[Image: screeny.gif]

I'm not sure why there is nothing being displayed for option 4 now. Sad lol, seems I am tied up in a mess of code. blah. Anyway, here is a link to my main.c file. This may help clear up any confusions you may have: http://www.ppenn.org/main.zip.

Thanks again for your help. Smile

~Achi
Quote this message in a reply
Moderator
Posts: 704
Joined: 2002.04
Post: #4
Er, if fileName is char[ 5 ][ 32 ], and you write to the file with fwrite( fileName, sizeof( fileName ), 5, fp );, surely you are writing 640 bytes (5 * 32 * (5 - 1 )) more than actually exist? And similarly for the reading of the file with fread( fileName, sizeof( fileName ), 5, fp );...

Mark Bishop
--
Student and freelance OS X & iOS developer
Quote this message in a reply
Moderator
Posts: 704
Joined: 2002.04
Post: #5
Er, you also don't write playNum to the file in the second of the code snippets, although playNum is read from that file in the first of the snippets... Assuming playNum is an int, I think you'll find not writing playNum is the origin of your missing four bytes...

Mark Bishop
--
Student and freelance OS X & iOS developer
Quote this message in a reply
Sage
Posts: 1,403
Joined: 2005.07
Post: #6
sizeof char[ 5 ][ 32 ] is 1

Sir, e^iπ + 1 = 0, hence God exists; reply!
Quote this message in a reply
Moderator
Posts: 704
Joined: 2002.04
Post: #7
printf( "%ld\n", sizeof( char[ 5 ][ 32 ] ));
$ 160

Mark Bishop
--
Student and freelance OS X & iOS developer
Quote this message in a reply
Luminary
Posts: 5,143
Joined: 2002.04
Post: #8
FYI, "%zu" is the right way to print a size_t Wink

But yes, unknown is talking through his hat.
Quote this message in a reply
Member
Posts: 21
Joined: 2009.05
Post: #9
Hey Sealfin,
First off, thanks for your input - very helpful. Smile

Quote:Er, if fileName is char[ 5 ][ 32 ], and you write to the file with fwrite( fileName, sizeof( fileName ), 5, fp );, surely you are writing 640 bytes (5 * 32 * (5 - 1 )) more than actually exist? And similarly for the reading of the file with fread( fileName, sizeof( fileName ), 5, fp );...
I see your point. I've changed it so that the code writes:
Code:
fwrite( fileName, sizeof( fileName[ 0 ] ), 5, fp );
This would write 32*5 = 160 bytes, correct? I am only using 128 of the written bytes, since I do not use fileName[ 0 ]. I don't understand how you got ( # * # * ( 5 - 1 ). Where does ( 5 - 1 ) come from?

Quote:Er, you also don't write playNum to the file in the second of the code snippets, although playNum is read from that file in the first of the snippets... Assuming playNum is an int, I think you'll find not writing playNum is the origin of your missing four bytes...
This is how I rewrote the loading system to avoid this:

Code:
//*******************************************
// Open & Read file "saves"
//*******************************************
    if ( ( fp = fopen( "saves", "rb" ) ) != NULL )
    {    
        fread( &playNum, sizeof( playNum ), 1, fp );
        fread( fileName, sizeof( fileName[ 0 ] ), 5, fp );
            
        fclose( fp );
    }
    else if ( ( fp = fopen( "saves", "rb" ) ) == NULL )
        if ( ( fp = fopen( "saves", "wb+" ) ) == NULL ) // -If no file is present, create one
        {
            printf( "Cannot open file." );
            exit( 1 );
        }
            
//*******************************************
// First Game - Add fileName content
//*******************************************
    if ( playNum == 1 )
        for ( counter = 1; counter < 5; counter++ )
            strcpy( fileName[ counter ], "--( U n u s e d )--" );
Right now, everything seems to work pretty well if you do not terminate the game after you use the delete function. If you keep going and then save your game at the Inn, everything is fine. However, if you delete a file, terminate the game, and then relaunch, all the files go blank. This leads me to think that within my EraseGame function, the fwrite function is not doing what it should be doing. Mad Right now, it seems to be writing blank information to the 'saves' file. That is why if you terminate the game and relaunch, everything is blank.

Now, I just have to figure out why the EraseGame: writef does not work - the code is the same with all my other save code. Blink

Well, I'm going to keep messing around with the code and see what I can think up. Smile Thanks again for your help. Grin

~Achi
Quote this message in a reply
Luminary
Posts: 5,143
Joined: 2002.04
Post: #10
Maybe you should print out sizeof(fileName[0]) -- I wouldn't like to guess offhand whether it's 32 (what you want it to be) or 4 (being sizeof(char*)).

If I were you, I'd have exactly one file-writing function, that you use from wherever it's needed. It can empty the file, then write a whole new one.
Quote this message in a reply
Member
Posts: 21
Joined: 2009.05
Post: #11
Quote:Maybe you should print out sizeof(fileName[0]) -- I wouldn't like to guess offhand whether it's 32 (what you want it to be) or 4 (being sizeof(char*)).
I did this a little bit ago when I was trying to find out what the correct size to pass to fwrite. It is 32 bytes, which makes sense if each char is 1 byte.

Quote:If I were you, I'd have exactly one file-writing function, that you use from wherever it's needed. It can empty the file, then write a whole new one.
This is a good idea. I think I will get working on it and see how it will improve my code. Smile

Quote:sizeof char[ 5 ][ 32 ] is 1
This makes the most sense to me... since 5 * 32 is 160, each char is = 1, right? I didn't put this in my code, so it's an educated guess. Rasp

Thanks for your help guys! Smile

~Achi
Quote this message in a reply
Moderator
Posts: 704
Joined: 2002.04
Post: #12
OneSadCookie Wrote:FYI, "%zu" is the right way to print a size_t Wink

/sealfin lives and learns Blush

Achithyn Wrote:I see your point. I've changed it so that the code writes:
Code:
fwrite( fileName, sizeof( fileName[ 0 ] ), 5, fp );
Yes, that would work, although I don't know why you don't just use fwrite( fileName, sizeof( fileName ), 1, fp );...

Achithy Wrote:Where does ( 5 - 1 ) come from?
Given fwrite( fileName, sizeof( fileName ), 5, fp ); in that code snippet, 5 is the number of times you actually write sizeof( fileName ) bytes, 1 is the number of times you want to write sizeof( fileName ); hence that code snippet results in you writing 4 * sizeof( fileName ), or 640 bytes, more than actually exist...

Mark Bishop
--
Student and freelance OS X & iOS developer
Quote this message in a reply
Member
Posts: 21
Joined: 2009.05
Post: #13
Hey guys,
Okay, all is well now. Smile Thank you for your help with this, I have learned a ton. Smile

The actual problem was, as Sealfin pointed out:
Quote:Er, you also don't write playNum to the file in the second of the code snippets, although playNum is read from that file in the first of the snippets... Assuming playNum is an int, I think you'll find not writing playNum is the origin of your missing four bytes...
I thought I knew what you meant at the time and made changes accordingly. It wasn't until a bit ago that it hit me, that when you use wb, you rewrite the file. Because I recreated the file, the new file did not have the int playNum. Because of this, I was missing four characters in front of my character data: fileName. Well, everything works very well now. Grin

I predict that I will have my Text RPG done in a few days. From there I only have a few more things to play with, and then I will check out Objective-C and Cocoa. Smile Thanks again for your help! I hope you all have a good one.

~Achi
Quote this message in a reply
Post Reply