Multiple errors in File Handling Program (Quiz Contest System)

I am supposed to develop a following program,
1
2
3
4
5
6
7
8
9
Quiz contest system is a simple database project. It is done using a file handling mechanism in C++. 
Minimum 10 questions and there options (in your case 4) with correct option will be saved in a file. In Second file information of 5 candidates will be saved.
Each candidate has to provide their information(in your case, Name, Registration Number, and Score. 
System has to search Name and Reg# of the candidate if found then start the contest.
If the provided option is correct then increase the score if wrong then decreases score with 1/4 of the correct answer. 
Then save score of each student in second file. Each student can appear only for the first time in the contest. 

Students are required to use the object oriented and functional approach to achieve the result. 
Hard code is not accepted.


So, I developed a program (I know it probably has many logical errors) but I am just trying to resolve some of the issues I am facing here.

Following is my code,

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
256
257
258
259
260
261
262
263
264
#include <iostream>
#include <string>
#include <cstring>
#include <fstream>
using namespace std;
class question
{
	string ques;
	string option[4];
	string correct;
	char *answer;
public:
	question() { answer = new char[20]; }
	void getdata();
	void showdata();
	char *getanswer();
	bool checkanswer(char *);
};
class student
{
	friend student getstudentname();
	friend void quiz(student &stu);
	string name;
	string reg;
	float score;
public:
	student() { score = 0.0; }
	void getdata();
	void showdata();
	bool operator==(student &);
};
void student::getdata()
{
	cout << "Name: ";
	getline(cin, name);
	cout << "Registration Number: ";
	getline(cin, reg);
}
void student::showdata()
{
	cout << "Student Name: " << name << endl
		<< "Registration ID: " << reg << endl
		<< "Score: " << score << endl;
}
bool student::operator==(student &s)
{
	if (this->name == s.name && this->reg == s.reg)
		return true;
	return false;
}
void question::getdata()
{
	cout << "Enter Question: ";
	getline(cin, ques);
	cout << "Enter Options: " << endl;
	for (int i = 0; i < 4; i++)
	{
		cout << "Option#" << i + 1 << ": ";
		getline(cin, option[i]);
	}
	cout << endl << endl << "Enter Correct Option: ";
	getline(cin, correct);
	bool fh = false;
	while (!fh)
	{
		for (int i = 0; i < 4; i++)
		{
			if (option[i] == correct)
			{
				fh = true;
				break;
			}
		}
		if (fh == false)
		{
			cout << "Invalid Option picked as Correct option" << endl
				<< "Enter Again: ";
			getline(cin, correct);
		}

	}
}
void question::showdata()
{
	cout << "Question: " << ques << endl
		<< "Options" << endl;
	for (int i = 0; i < 4; i++)
	{
		cout << option[i] << endl;
	}
	//cout << "Correct Option: " << correct << endl; 

}
char *question::getanswer()
{
	cout << "Your Answer(case-sensitive): ";
	cin.getline(answer, 20);
	return answer;
}
bool question::checkanswer(char *ans)
{
	if ((strcmp(this->answer, ans)) == 0)
		return true;
	return false;
}
question obj[10];
student st[5];
bool strecord[5];
bool checkstu = true;
void getquestions();
void quiz(student &);
void getstudents();
student getstudentname();
int main()
{
	student temp;
	bool fh = true;
	for (int i = 0; i < 5; i++)
		strecord[i] = false;
	while (fh)
	{
		cout << "Please pick your option" << endl
			<< "1) Enter new Questions" << endl
			<< "2) Enter new Students" << endl
			<< "3) Start Quiz" << endl
			<< "4) Quit the Program" << endl
			<< "Your choice: " << endl;
		int choice;
		cin >> choice;
		getchar();
		switch (choice)
		{
		case 1:
			getquestions();
			break;
		case 2:
			getstudents();
			break;
		case 3:
			temp = getstudentname();
			if (checkstu)
				quiz(temp);
			break;
		case 4:
			fh = false;
			break;
		default:
			break;
		}
	}
	system("pause");
	return 0;
}
void getquestions()
{
	system("cls");
	question temp;
	ofstream fout;
	ifstream fin;
	remove("Questions.dat"); // To remove old file. 
	for (int i = 0; i < 2; i++)
	{
		temp.getdata();
		fout.open("Questions.dat", ios::app | ios::binary);
		fout.write((char *)&temp, sizeof(obj[i]));
		//obj[i] = temp; 
		fout.close();
		system("cls");
	}

}
void quiz(student &stu)
{
	question temp;
	char *ans;
	int i = 1;
	ifstream fin;
	fin.open("Questions.dat", ios::in | ios::binary);
	fin.read((char *)&obj[0], sizeof(obj[1]));
	while (!fin.eof())
	{
		fin.read((char *)&temp, sizeof(obj[1]));
		obj[i] = temp;
		i++;
	}
	for (int j = 0; j < i - 1; j++)
	{
		obj[j].showdata();
		ans = obj[j].getanswer();
		if (obj[j].checkanswer(ans))
			stu.score = stu.score + 1;
		else
		{
			stu.score = stu.score - 0.25;
			if (stu.score < 0)
				stu.score = 0;
		}
		system("cls");
	}
	cout << "Student Name: " << stu.name << endl
		<< "Registration ID: " << stu.reg << endl
		<< "Score: " << stu.score << endl
		<< "Record saved..." << endl;
	ofstream fout;
	fout.open("Student Record.dat", ios::app | ios::binary);
	fout.write((char *)&stu, sizeof(stu));
	fout.close();
	cout << "Press Enter to continue.";
	getchar();
	system("cls");

}
void getstudents()
{
	system("cls");
	student temp;
	ofstream fout;
	ifstream fin;
	remove("Students.dat"); // To remove old file. 
	for (int i = 0; i < 1; i++)
	{
		temp.getdata();
		fout.open("Students.dat", ios::app | ios::binary);
		fout.write((char *)&temp, sizeof(st[i]));
		fout.close();
		system("cls");
	}
}
student getstudentname()
{
	student temp, temp1;
	int i = 1;
	cout << "Enter Student Name(case sensitive): ";
	getline(cin, temp.name);
	cout << "Enter Registration ID: ";
	getline(cin, temp.reg);
	ifstream fin;
	fin.open("Students.dat", ios::in | ios::binary);
	fin.read((char *)&st[0], sizeof(st[1]));
	while (!fin.eof())
	{
		fin.read((char *)&temp1, sizeof(st[1]));
		st[i] = temp1;
		i++;
	}
	for (int j = 0; j < i - 1; j++)
	{
		if (temp == st[j])
		{
			checkstu = true;
			if (strecord[j] == true)
			{
				cout << "Student has already given his test";
				checkstu = false;
			}
			else
				strecord[j] = true;
			return temp;
		}
	}
	cout << "No Student Found with current name and registration ID";
	checkstu = false;
	return temp1;
}


The first problem I am facing is on line 102 (strcmp function) which is returning the value at line 190... It add the score but it is adding 1 in score even when the answer is correct (when it should be returning false). Can anyone explain the issue?


Second problem, the program doesn't execute completely. Once it is done executing all the function, it breaks down and doesn't end. I couldn't understand the error I was getting there..


Third and probably the most important problem, I am unable to read the files properly once they have been created. For example, I entered new Questions and wrote them to "Questions.dat". During "that" program, when I go for the quiz, question appears correctly and user is able to give answers correctly. No exception is thrown... However, if I close the program, and run it again and then start a quiz then questions appear but when I give some answer to any of the question, the program breaks down due to some error, something which again I am unable to understand.
Can anyone help me out identifying the issue, please?
Thank you!

(Just to be clear, I have reduced the loop to only 2 questions and 1 student for checking of program... and also, I am supposed to check Student Record file instead of that bool array which I am using to check if the user has already given the quiz. These issues along with few others, I will check and correct later but the ones I mentioned are kind of difficult for me to identify :/
Last edited on
I see you're using std string, and also char arrays. I think you'd do youself a favour if you stopped using char arrays and just stuck to strings. Then you wouldn't have to worry about strcmp. You also wouldn't have to worry about whether or not your char-pointers were valid and also not worry about memory leaks; both of which look like things that can happen in your code at the moment.
Last edited on
Third and probably the most important problem, I am unable to read the files properly once they have been created.

This is because you're trying to write structures that contain non-trivial classes, std::string in this case. When you try to write() a std::string in binary mode you actually write some pointers, not the actual string. I recommend you abandon the binary mode, including the read(), write() functions and just use text mode. Then overload the insertion and extraction operators to write and read the file in text mode. You may want to consider using a CSV type of file structure.

binary works on anything, of course. something like (Im a little rusty, all our files are bloated xml text sadly) this is what you should do to write a string to a binary file.
file.write(string.length(), sizeof(size_t)); //you can used a fixed size here instead if you want to pad to have fixed length records and know your data WELL.
file.write(&stringvar[0], stringvar.length())

that said, working in binary (as said already) is not ideal here. But you should know how to do this, as it WILL come up again when you DO want a binary file.

Last edited on
Topic archived. No new replies allowed.