Reading binary file problem

The first run of the program gets book information and writes the objects to a binary file. The second run of the program reads the objects from the binary file into an array. Everything seems to work fine, but at the end of the second run the program crashes. When I remove read from binary, the second run does not crash.

read from binary file
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
myFile2.open("CheckedOutBooks.dat", ios::in | ios::binary);
	if (myFile2.is_open())
	{
		myFile2.seekg(0);
		for (int k = 0; k < counter; k++)
		{
			myFile2.read(reinterpret_cast<char*> (&book), sizeof(Book));
			newBook[k] = book;

			if (myFile2.eof())
				break;
			bookCounter++;
			counter++;

			cout << book.getFirstName();
			cout << book.getLastName();
			cout << book.getTitle();
			cout << book.getDueDate();
			cout << endl;
		}
		myFile2.close();
	}
	else
		cout << "Cannot open file." << endl;


main
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
#include <iostream>
#include <iomanip>
#include <string>
#include <fstream>
#include "book.h"
using namespace std;

int main()
{
	string last, first, title;
	char input;
	int bookCounter = 0, month = 0, day = 0, year = 0, counter = 1;
	Book book;
	Book newBook[10];  // assume no more than 10 books
	fstream myFile, myFile2;

	myFile2.open("CheckedOutBooks.dat", ios::in | ios::binary);
	if (myFile2.is_open())
	{
		/*myFile2.seekg(0);*/
		for (int k = 0; k < counter; k++)
		{
			myFile2.read(reinterpret_cast<char*> (&book), sizeof(Book));
			newBook[k] = book;

			if (myFile2.eof())
				break;
			bookCounter++;
			counter++;

			cout << book.getFirstName();
			cout << book.getLastName();
			cout << book.getTitle();
			cout << book.getDueDate();
			cout << endl;
		}
		myFile2.close();
	}
	else
		cout << "Cannot open file." << endl;

	cout << "Welcome to CS library program." << endl;
	cout << "Please enter the date in integers according to the following format -\n" <<
		"mm dd yyyy: ";
	cin >> month >> day >> year;
	cout << endl;

	Date date(month, day, year);
	Date due(month, day, year);
	due.operator+=(14);

	do
	{
		cout << "Please enter your one letter choice as follows:" << endl;
		cout << "  C:  Check out a book\n";
		cout << "  D:  Check in a book\n";
		cout << "  T:  Print all books currently checked out\n";
		cout << "  Q:  quit this program\n";
		cin >> input;

		switch(input)
		{
		case 'C':
		case 'c':
			{
				cout << endl;
				cout << "Please enter one line consisting the first and " <<
					"last names of the author followed by the title of the book." << endl;
				cin >> first >> last;
				getline(cin, title);

				book.setFirstName(first).setLastName(last).setTitle(title).setCheckOutDate(date).setDueDate(due);
				newBook[bookCounter] = book;
				bookCounter++;
			}
			cout << endl;
			break;
		case 'D':
		case 'd':
			{
				cout << endl;
				cout << "Please enter one line consisting the first and " <<
					"last names of the author followed by the title of the book." << endl;
				cin >> first >> last;
				getline(cin, title);

				Book temp;
				temp.setFirstName(first).setLastName(last).setTitle(title);

				for (int i = 0; i < bookCounter; i++)
				{
					if (newBook[i].getFirstName() == temp.getFirstName() 
						&& newBook[i].getLastName() == temp.getLastName()
						&& newBook[i].getTitle() == temp.getTitle())
					{
						cout << "Found." << endl;
						if (newBook[i].getDueDate().operator<(date))
						{
							cout << endl;
							cout << "This book is overdue." << endl;
						}
						for (i; i < bookCounter; i++)
						{
							newBook[i] = newBook[i + 1];
							bookCounter--;
						}
					}
					else
						cout << "Not found." << endl;
				}
			}
			cout << endl;
			break;
		case 'T':
		case 't':
			cout << "Author" << setw(10) << "Title" << setw(30) << "Check Out Date" << setw(10) << "Due Date" << endl;
			for (int i = 0; i < bookCounter; i++)
			{
				cout << newBook[i].getLastName() << ", " << newBook[i].getFirstName() << setw(15) << newBook[i].getTitle() 
					<< setw(20) << newBook[i].getCheckOutDate() << " " << newBook[i].getDueDate() << endl;
			}
			cout << endl;
			break;
		case 'Q':
		case 'q':
			{
				myFile.open("CheckedOutBooks.dat", ios::out | ios::binary);
				if (myFile.is_open())
				{
					for (int k = 0; k < bookCounter; k++)
					{
						myFile.write(reinterpret_cast<char*> (&newBook[k]), sizeof(newBook[k]));
					}
					myFile.close();
				}
				else
					cout << "Cannot open file." << endl;
			}
			break;
		default:
			cout << "Invalid choice. Enter C, D, T, or Q." << endl;
			cout << endl;
		}
	} while(!((input == 'Q') || (input == 'q')));

	return 0;
}
myFile.write(reinterpret_cast<char*> (&newBook[k]), sizeof(newBook[k]));

This doesn't work unless Book is a POD type.

I explain why this is a problem and how to solve it in this thread:

http://www.cplusplus.com/forum/beginner/30826/#msg167057


EDIT:

and some other in-depth articles on the subject:

http://www.cplusplus.com/articles/DzywvCM9/
http://www.cplusplus.com/articles/oyhv0pDG/
Last edited on
> The first run of the program gets book information and writes the objects to a binary file.

Do you really need a binary file format for storing and retrieving information about books?

When you feel the urge to design a complex binary file format, or a complex binary application protocol, it is generally wise to lie down until the feeling passes. http://www.faqs.org/docs/artu/ch05s01.html


By default, read and write plain text.
Yeah I have to use a binary file. For some reason my program works fine on my other computer.
Topic archived. No new replies allowed.