• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 499
  • Last Modified:

problem with fwrite

Hi,

I am using fwrite to write the content of a structure into a file.

struct rec {
        int age;
        char name[10];
        };

FILE * pFile;
pFile = fopen ("myfile.txt","w");
var1.age = 30;
        strcpy(var1.name,"gyan");
        var1.name[4] = '\0';

        fwrite((void *)(&var1),sizeof(struct rec),1,pFile);
        fflush(pFile);
        fclose(pFile);

Now if i open myfile.txt, then ot shows like this:

^^gyan^Cÿ¾ì<

show it is showing string field but not integer field and also showing some junk thing?

I have read somewhere that "fwrite" doesn't pring Linefead and carriage Return like fputs.
But, if that is true then i think, output file should content all records(In case i write multiple records in file through fwrite) in single line.But resultant file something more ambiguous then expected.
Can someone help!!!!!!!

One more strang thing , i found.
If i open 2 file ponters .(FILE *)
1st is for writing into some file in "w" mode.
Then i wrote something into file.
Then i closed that file pointer.


Now i open 2nd file pointer for reading something from a other file.
Now if i try to read 1st file pointer(i know this is wrong, since i have already closed that one), then it is showing contents of file, which has been opened in read mode!!!!!!!!!
Means 2 file pointer is linked to same file, when i have already closed 1st File pointer, but it is still live!!!!!
0
pattha
Asked:
pattha
1 Solution
 
Harisha M GCommented:
Hi pattha,
    That is the drawback of C :(
    You can try this...
    fprintf(pFile,"%d%s",var1.age,var1.name);

Bye
---
Harish
0
 
Harisha M GCommented:
pattha,
> Now i open 2nd file pointer for reading something from a other file.
> Now if i try to read 1st file pointer(i know this is wrong, since i
> have already closed that one), then it is showing contents of file,
> which has been opened in read mode!!!!!!!!!

May be.. because, when you first created a pointer, say, pF1 it was given an address say 1000
When you closed that, the memory location 1000 is freed. Now if you opened another file then, again the same memory location *may have been* used, which means, you get the same file with both the pointers :^)
0
 
stefan73Commented:
Hi pattha,
> ^^gyan^Cÿ¾ì<
> show it is showing string field but not integer field and also showing some junk thing?

Yes, because you didn't initialize your struct properly. use
memset(&var1,0,sizeof(var1));

The int is showing in the first four bytes, it's binary data.

Cheers!

Stefan
0
Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
brettmjohnsonCommented:
When you use fwrite() to write out the structure, it writes the binary representation of the structure as it is laid out in memory.   Your attempt to interpret this binary data as text will fail.  The first ^^ are the age, where bytes of the binary integer are interpreted as
ASCII characters.  The "junk" following 'gyan' are the remaining unoccupied 5 bytes of your 10 byte name buffer.

This mechanism for archiving the state of a program as raw binary data is often used, because it can be written and read quickly.  However it has several serious drawbacks:
 - The structures cannot contain pointers (memory addresses)
 - They must be read on the machine architecture (word size, byte order, structure member alignment) as written
 - If you add a member or change the size of a structure member, the archived state cannot be read.
 - As you found, the archive is not human readable, if something goes wrong or you wish to exchange the data with another application, you need to painfully reverse engineer the format.

The act of archiving a program's state to a stream or file by writing out the state of its structures or objects is called "serialization".
You can find more information here (it discusses serialization in Java rather than C, but the idea is the same):
http://www.acm.org/crossroads/xrds4-2/serial.html

Harish's example shows how to overcome many of the above drawbacks, by serializing the structure as ASCII string values.


> I have read somewhere that "fwrite" doesn't pring Linefead and carriage Return like fputs.

That is correct.  fwrite maps almost directly to the lower level write() call, writing only the buffer of data provided.  That data is not embellished in any way.  Functions like fputs() and fprintf() can be used if you wish to embellish the output or modify its layout or encoding.



0
 
stefan73Commented:
Yes, ASCII serializing may be a good idea. But there are several pitfalls. You need either a separator, or fixed-size fields. A typical separator format is Excel's CSV format. If you have lots of fields in different sizes, using a separator is sensible. Fixed-size fields are easier to program, but they waste space when the fields are not fully used.

You could start with a CSV-compatible format, as it's simple and there are lots of code examples on the web.

ASCII data requires a lot more effort to read than plain structures, though.

Stefan
0
 
novitiateCommented:
>>>>That is the drawback of C :(

Its not draw back, but the way it works and its upto you decide how to use.

Binary or Text, Binary data is very useful for reading and writing data to files, whereas text mode should be used when you want data to be readable to humans.

_novi_
0
 
grg99Commented:
You have to decide: do you want the file to be human-readable or just computer readable.

If you use fwrite, the computer can read and write it, but it will look funny to humans.

If you use fprintf, it will look better to humans,  but be a  little slower to read.

... and what's happening when you read the file after you closed it is:  when you closed it, that file handle (a small integer) get released.  Then when you open the other file, that same file handle gets assigned again.  Then if you try to use the original FILE *, it has the same file handle in it as the second opened file, so both FILE *'s are effectively pointing to the same file.  Not a good thing.    Don't use file pointers after you close them.  Just to be sure, assign NULL to the file ponter right after the close so you don't have access to the struct.



0
 
Harisha M GCommented:
>>>>That is the drawback of C :(

>>Its not draw back, but the way it works and its upto you decide how to use.

That is not my intension... I was simply telling the drawback of C over C++ where you can overload >> to do the thing :) or use streams available instead of FILE * !!
0

Featured Post

Concerto's Cloud Advisory Services

Want to avoid the missteps to gaining all the benefits of the cloud? Learn more about the different assessment options from our Cloud Advisory team.

Tackle projects and never again get stuck behind a technical roadblock.
Join Now