Problem with writing to a file

Hi. This is my first post in this awesome forum.

I have problem with these codes:

#include<iostream>
#include<fstream>
using namespace std;
class Book
{
	char title[20], author[15];
	float price;
	int quantity;
public:
	void ask();
};
void Book::ask()
{
	cout<<"\nWhat is the title? ";
	cin.getline(title, 19);
	cout<<"who is the author? ";
	cin.getline(author, 14);
	cout<<"What is the price? ";
	cin>>price;
	cout<<"how many are there? ";
	cin>>quantity;
	cin.get();
}
void main(){
	Book book1, book2, book3;
	ofstream outf("BOOK.DAT");
	cout<<"*Book inventory*\n";
	book1.ask();
	outf.write((char*)&book1, sizeof(book1));

	book2.ask();
	outf.write((char*)&book2, sizeof(book2));

	book3.ask();
	outf.write((char*)&book3, sizeof(book3));
}

When writing to the file, Instead of correct record information, always something like this goes to file:
Sara جججججججججججججججMe ججججججججججججج ب

Apparently the code is completly correct, but what's wrong with the compile and execution?
outf.write((char*)&book1, sizeof(book1));


You are telling your compiler, that the class "Book" should be treates as if it were just a normal sequence of characters.

Book probably looks like this in memory:

- 20 bytes of "title"
- 15 bytes of "author"
- 1 byte padding to reach 4-byte-alignment
- 8 bytes of "price"
- 4 bytes of "quantity"

Except the title and author, they aren't anything like character sequences and even these fields are not completely filled with characters.

But with your outf - line, you are telling the compiler: "shut up, just print the memory-stuff as if it were characters." (The (char*) - thing is the equivalent of "shut up" ;-)

So now it makes sense that you see the garbage output? :)

You most probably do not want to just save the memory state of your book-class unencoded to disk (you will have trouble getting it back later). You may want to save it structured, e.g. line-wise printing out
every member field separately and then read it in like you read from "cin" now.

Ciao, Imi.
Grazie but considering this code:

1
2
3
4
5
6
7
8
9
#include<iostream>
#include<fstream>
using namespace std;
void main()
{
	int a=123;
	ofstream oFile("myFile.dat");
	oFile.write((char*)&a, sizeof(a));
}


again the same problem! now instead of putting 123 to the myfile.dat, the content of myfile.dat is this mark "{"

again, the same problem. by writing "(char*)&a" you are saying:

"I have an int called 'a'. Take the memory address of this int (&a) and now just shut up and do as if it would be a pointer to a character array ((char*)&a). Then write this into the file.

So what you get is the memory how it looks for your compiler to store an integer but interpreted as character string.

If you expected a result like "123" written into the file, just do this:

1
2
3
int a = 123;
ofstream oFile("myFile.dat");
oFile << a << endl;


This uses the << - operator, which is clever enough to see, that you have an integer. It will convert
the integer into a "123" and write this in plain ASCII text into your file. The "<< endl" is to add an enter after the number.

For how to handle ofstream - file I/O and all this << stuff, you probably can consult the same source that teached you how to use "cout <<" and "cin >>" ;-)

Ciao, Imi.
imi is correct..

you can watch this open courseware from stanford university to understand this if you have time, http://www.youtube.com/watch?v=jTSvthW34GU
Thank you imi but I knew what the code you put here does. I actually have worked with << and >> for writing to file and reading from file so much, but the problem is this:

I WANT TO USE WRITE() INSTEAD OF << AND IT DOESN'T WORK.
So how can I get the same result with using write() instead of << ?

Thank you again and thank you blackcoder41 for putting the link.
I WANT TO USE WRITE() INSTEAD OF << AND IT DOESN'T WORK.


Well, if you want to achieve the same result as with <<, then you have to properly convert the integer into a character string first. (Funny, because the standard recommendation on how to do this is using a stringstream and << again ;-).

Then, when you have a const char* (or std::string and you call to .c_str() ), you can write this with write out into a file.

Ciao, Imi.
Got the answer!

After using write() and putting things into the file, I used casting again for reading that file and it worked. Here is the code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include<iostream>
#include<fstream>

using namespace std;

void main(){
    int a=123;
    ofstream oFile("myFile.dat");
    oFile.write((char*)&a, sizeof(a));
    oFile.close();
    ifstream iFile("myFile.dat");
    int b;
    iFile.read((char*)&b, sizeof(int));
    cout<<b;
Use int main().

Anyway, that will work, but then you have to remember how long everything you put in there is, and if anything is slightly different (your c string size, int size, etc) then your reading will produce incorrect results.
well that will not always work.. what if your Book class have a string object member? found out what happens..
What you mentioned was exactly what I was going to ask.
Now how can I add a string object member to a binary file? Can I use << operator? If so then how can I read that string correctly with read()? I examined this and the result was AHHHHH!
Maybe working with binary files is ...
The insertion and extraction operators ( << and >> ) both have built-in conversion. They're intended to handle all those little details for you behind the scenes, and thus why they are recommended.

read() and write() provide none of those capabilities for you. You have to handle all that yourself. The question of HOW to handle those details is really up to you.

So the obvious question at this point is, if you are familiar with >> and << and have successfully used them already, why do you not want to use them now?
Topic archived. No new replies allowed.