BINARY FILE READ ERROR

I'm studying my higher secondary and I am working on this project for my final exams... I'm saving the details in a binary file after user enters their values. I'm able to read, modify and display the file contents at an instance... but after closing and opening it again the binary file is able to open the file but the details are not displayed... program stops with 255 value.

I have closed the files after each manipulation but the file contents are not displayed and program crashes...

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
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
  #include <iostream>
#include <string>
#include <vector>
#include <fstream>
#include <windows.h>

using namespace std;

bool state=false;

class recipe
{
	char			c;
	string          rname;
	string			category;
    vector<string>  ingredients;
    vector<string>  units;
    vector<int>     quantity; 
    vector<string>  instructions;
    int     		qcount,icount;
    int     		qty;
    string  		unit;
    string  		ingred;
    string  		instruct;
    //bool			state;
    
    public:
		
	recipe()
	{
		state = false;
	}
		
    void Add_Recipe()
    {
    cout<<"\nEnter Recipe name :";
    cin>>rname;
    cout<<"\nEnter No.of.Ingredients :";
    cin>>qcount;
    for(int i=0; i<qcount; i++)
    {   
		cout<<"\nEnter quantity unit and ingredients ";
	    cin>>qty>>unit>>ingred;
	    quantity.push_back(qty);
	    units.push_back (unit);
	    ingredients.push_back (ingred);
	}
    cout<<"\nEnter No. Of Instructions :";
    cin>>icount; 
    cin.ignore();
    for(int i=0; i<icount; i++)
    	{	cout<<"\nEnter Instructions below :\n";
        	getline (cin, instruct); 
        	instructions.push_back (instruct); 
   		}
   	cout<<"Do You Want to Surely Add The Recipe Detail To File (y/n) :";
    cin>>c;
    if(c=='y'||c=='Y')
    state = true;
    else
    state = false;		
   	
	}
	
	void Modify_Recipe()
	{
	/*cout<<"\nOld Recipe Details :\n";
	cout<<rname<<endl;
    for(int i=0; i<qcount; i++) 
    	{	
			cout<<quantity[i]<<" "<<units[i]<<" "<<ingredients[i]<<endl;
		}
    	for(int i=0; i<icount; i++) 
    	{	 
		  	cout<<instructions[i]<<endl; 
    	}*/
    cout<<"\nEnter Modified Recipe Details :";
    cout << "\nEnter Recipe name :";
    cin>>rname;
    cout<<"\nEnter No.of.Ingredients :";
    cin>>qcount;
    for(int i=0; i<qcount; i++)
    {
	   	cout<<"\nEnter quantity unit and ingredients ";
	   	cin>>qty>>unit>>ingred;
	   	quantity.push_back(qty);
	   	units.push_back (unit);
	   	ingredients.push_back (ingred);
	}
    cout<<"\nEnter No. Of Instructions :";
    cin>>icount; 
    cin.ignore();
    for(int i=0; i<icount; i++)
    {  
		cout<<"\nEnter Instructions below :\n";
       	getline (cin, instruct); 
       	instructions.push_back (instruct); 
    }
    cout<<"Do You Want to Surely Update The Recipe Details (y/n) :";
    cin>>c;
    if(c=='y'||c=='Y')
    state = true;
    else
    state = false;
	}
	
	void Display_Recipe()
	{
		cout<<"\nRecipe Details :\n";
    	cout<<rname<<endl;
    	for(int i=0; i<qcount; i++) 
    	{	
			cout<<quantity[i]<<" "<<units[i]<<" "<<ingredients[i]<<endl;
		}
    	for(int i=0; i<icount; i++) 
    	{	 
		  	cout<<instructions[i]<<endl; 
    	}
	}
	
	string Search()
	{
		return rname;
	}
	
};

int main()
{
	 recipe r;
	 int c;
	 do
	 {
	 cout<<"\t\tCOOKING ASSISTANT";
	 cout<<endl<<"1.START COOKING"<<endl;
	 cout<<endl<<"2.ADD NEW RECIPE"<<endl;
	 cout<<endl<<"3.MODIFY RECIPE"<<endl;
	 cout<<endl<<"4.DELETE RECIPE"<<endl;
	 cout<<endl<<"5.VIEW ALL RECIPES"<<endl;
	 cout<<endl<<"6.EXIT"<<endl;
	 cout<<endl<<"ENTER YOUR CHOICE (1-6): "<<endl;
	 cin>>c;
	 switch(c)
	 {
		 case	1	:	{
		 				cout<<"NOT CONFIGURED";
						break;
						}
						
		 case	2	:	{
		 				system("cls");
						ofstream data("F.DAT",ios::binary | ios::app);
		 				r.Add_Recipe();
		 				if(state==true)
		 				{
		 					data.write((char*)&r,sizeof(r));
		 					cout<<"\nRecipe Added...";
		 					break;
						 }
						else
						cout<<"\n Recipe Not Added...";
						data.close();
						cout<<"File Stream Closed";
						break;
		 				}
						
		 case	3	:	{
		 				system("cls");
		 				fstream data("F.DAT",ios::binary | ios::app | ios::in);
		 				string searchstr;
		 				cout<<"\nEnter Recipe Name To Modify :";
		 				cin>>searchstr;
		 				while(!data.eof())
		 					{
		 						data.read((char*)&r,sizeof(r));
		 						if(!searchstr.compare(r.Search()))
								{
								 	if(state==true)
								 	{
								 		r.Modify_Recipe();
										data.seekp(-1*sizeof(r),ios::cur);
								 		data.write((char*)&r,sizeof(r));
								 		cout<<"\nRecipe Modified...";
								 		break;
								 	
									}
									else
									{
										cout<<"\nRecipe Is Not Modified...";
										break;
									}
								}
							break;
							}	
						data.close();
						cout<<"File Stream Closed";
						break;	 					
						}
		
						
		
		 case 	4	:	{
		 				system("cls");
		 				string searchstr;
		 				fstream data("F.DAT",ios::binary | ios::app | ios::in);
		 				ofstream del("TEMP.DAT",ios::binary | ios::out);
		 				cout<<"\nEnter Recipe Name To Delete :";
		 				cin>>searchstr;
		 				while(!data.eof())
		 				{
		 					data.read((char*)&r,sizeof(r));
		 					if(searchstr.compare(r.Search()))
							 {
							 	del.write((char*)&r,sizeof(r));
							 }		 					
						 }
						del.close();
						data.close();
						cout<<"File Stream Closed";
						remove("F.DAT");
						rename("TEMP.DAT","F.DAT");
						cout<<"\nRecipe Deleted...";
						break;
		 				}
						
		 case	5	:	{
		 					system("cls");
							ifstream data("F.DAT",ios::binary | ios::in);
							if(data.is_open())
							{
								data.seekg (0, ios::beg);
								cout<<"File Opened...";
								while(!data.eof())
								{
	 					   	 		data.read((char*)&r,sizeof(r));
									r.	Display_Recipe();
									break;
								}
							}
							else
							cout<<"File Is Not Readable...";
						data.close();
						cout<<"File Stream Closed";	
						break;
						}
			
		 case	6	:	exit(0);
						break;
						
		default		:	cout<<endl<<"Invalid Choice !";
						break;
	 }
	}while(c!=6); 
} 
Last edited on
Your class recipe is not POD.

See this FAQ on serialization:
https://isocpp.org/wiki/faq/serialization

Prefer text formats where possible.
Last edited on
I don't understand what you are saying... I am not well versed in c++ can you please say what I should do exactly ?
You're trying to serialize recipes - that is, to write them out completely and then restore them at a different time and place. That is not as simple as a reinterpret_cast to a block of char* char.

Regardless of machine-dependent details like endianness and packing, imagine a variable a initialized like this
 
class A { int* ptr; } a{new int{42}};

That structure contains a single pointer to int. If you write it out as a block of char, you'll record the value of the pointer, but you will not record the value the pointer refers to. And depending on the rest of the program and the environment, it's quite likely that the pointer itself would be invalid or point to the wrong thing upon restoration.

std::vector and std::string certainly cannot be "serialized" in this way and restored completely later, so neither may any object which contains them.

The "easy" way to do this is to store your recipes as text. You will need to define a routine to convert recipe records to and from some text encoding, and write those records to a file.

The FAQ entry I listed previously discusses the problem and the trade-offs a little more.
Last edited on
Topic archived. No new replies allowed.