-4

I just can't understasnd how fwrite finction works in c.I had made a c program.here it it:-

#include <stdio.h>

int main()
{
struct books
{
    char name[100];
    float price;
    int pages;
}book1;

puts("enter the name of the book");gets(book1.name);
puts("enter the price of the book");scanf("%f",&book1.price);
puts("enter the pages of the book");scanf("%d",&book1.pages);

FILE *b=fopen("Book.txt","w");
fwrite(&book1,sizeof(book1),1,b);
}

here is input of th program:-

 $ ./a.out 
 enter the name of the book
 Voldemort the last BSD user
 enter the price of the book
 40000
 enter the pages of the book
 34

and here is the content of the file:-

 $ cat Book.txt 
  Voldemort the Great Linux and bsd user!����c����@�@��,B

Thus what is wrong in my program ? How does fwrite works ? When should I use it?

2 Answers2

0

Nothing is immediately wrong with your program, except that you use gets(), which is very wrong (a guaranteed buffer overflow), but has nothing to do with your question, so I just leave the hint here: Use fgets() and for general information how to reliably get input in C, I recommend reading

As for your question, fwrite() writes whatever you give it to a file in exactly the same way it's in the memory of your computer. You could read this same file again with fread() and end up with the same struct. But be aware the representations of data types are implementation defined. So you can't for example read this file on a different machine, or even on the same machine with a program compiled using a different compiler. Therefore, using fwrite() to write whole structs is of very limited use in practice.

As for why you see "strange stuff" with cat, that's simply because cat interprets all file contents as characters. You would see the same if you would just write your float and int to stdout directly, instead of formatting it with printf().

To write structs in a portable way to a file, you have to apply some sort of data serialization. A very simple way would be to use fprintf() with a sensible format string. There are many possibilities to do that, you could e.g. use a JSON format with an appropriate JSON library, same goes for XML.

-2

This is correct. The fwrite writes write file binary making the exact copy of the memory occupied by your structure in your file. If you want to save binary members / fields in the text form you need to serialize it ie convert binary data to text and write the converted ones to the file.

for example instead of fwrite use fprintf

  fprintf(b, "%s,%f,%d\n", book1.name, book1.price, book1.pages);
Gianluca Ghettini
  • 11,129
  • 19
  • 93
  • 159
0___________
  • 60,014
  • 4
  • 34
  • 74
  • So `fwrite` is used for writing binary ?? –  Aug 04 '17 at 10:39
  • 3
    @voldimot everything is binary data, "text data" is just binary data plus a given interpretation of such data – Gianluca Ghettini Aug 04 '17 at 10:40
  • 1
    @PeterJ I think OP's fwrite solution and yours solution are both valid. What we are missing here is the format in which store such data to a file – Gianluca Ghettini Aug 04 '17 at 10:43
  • @Gianluca Ghettini it not about the validity, but about the idea. OPs file name has the .txt extension - which usually means : text. Text means - human readable content – 0___________ Aug 04 '17 at 10:45
  • 1
    @voldimot Roughly yes. `fwrite` is used to write the memory content verbatim (often called binary data), `fprintf` to produce a "string" representation of the data (often called text). But Gianluca is right, in computer world, everything is binary at the end. – Jean-Baptiste Yunès Aug 04 '17 at 10:46
  • @PeterJ of course, but you are implicitly adding an arbitrary format: comma separated values stored in decimal as text. Perfectly fine but is this what we want? who (or what) is going to read the file? – Gianluca Ghettini Aug 04 '17 at 10:48
  • @Gianluca Ghettini you have missed the very important word: "example". – 0___________ Aug 04 '17 at 10:52