need help figuring out why 4/n 5/n 6... is printed the the screen

Hello, I can't seem to figure out why my program is printing out 4/n 5/n 6/n to the screen when ever I select 1 on the menu which is load quiz. I have looked through the code multiple times from top to bottom and can't seem to see what I did to make this happen. Every time I select load quiz the program says:
You selected - Load quiz.
4
5
6
then it brings the menu back up and everything works as it should. Can anyone help me figure this out. It would be greatly appreciated. Thank in advance for any help. My code is below.
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
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
  #include <iostream>
#include <string>
#include <fstream>
#include <cstdlib>


class questions
{
private:
	std::string question;
	std::string answer;
	int value;
	std::string questionType;
public:

	std::string getQuestion()//gets the question
	{
		return question;
	}

	virtual int getValue() //gets the point value of the question
	{
		return value;
	}

	virtual std::string getQuestionType()// gets the type of question
	{
		return questionType;
	}


	virtual void setQuestion(std::string answer, int value)
	{
	}
	virtual void setNewQuestion(std::string answer, int value)
	{
	}
	virtual void printOptions()
	{
	}

	virtual std::string getAnswer()
	{
		return answer;
	}
};


class QuestionTF : public questions// class for true and false questions
{
private:
	std::string question;
	std::string questiontype;
	std::string answer;
	std::string options;
	int value;
public:
	void setQuestion(std::string theQuestion, int pointValue)
	{
		std::string theAnswer;
		questiontype = "TF";
		question = theQuestion;
		value = pointValue;
		options = "true/false";
		//get the answer from the file
		std::getline(std::cin, theAnswer);
		answer = theAnswer;
	}

	void setNewQuestion(std::string theQuestion, int pointValue)
	{
		std::string theAnswer;
		questiontype = "TF";
		question = theQuestion;
		value = pointValue;
		options = "true/false";
		//get the answer from user
		std::cout << "Enter answer true/false\n";
		std::getline(std::cin, theAnswer);
		answer = theAnswer;
	}

	int getValue() //gets the point value of the question
	{
		return value;
	}

	std::string getQuestionType()// gets the type of question
	{
		return questiontype;
	}

	void printOptions()//prints the options for that question
	{
		std::cout << question << std::endl;
		std::cout << answer << std::endl;
	}

	std::string getAnswer()//outputs the answer for that question
	{
		return answer;
	}
};



class QuestionMC : public questions//class for multiple choice
{
private:
	int numberOfOptions;
	std::string question, answer;
	std::string options[6];
	std::string questiontype;
	int value;
public:
	void setQuestion(std::string theQuestion, int pointValue)
	{
		std::string line;
		questiontype = "MC";
		std::getline(std::cin, line);
		numberOfOptions = atoi(line.c_str());
		std::cout << numberOfOptions << std::endl;
		question = theQuestion;
		value = pointValue;
		//get the individual choice lines and load to options array
		for (int count = 0; count < numberOfOptions; count++) {
			std::getline(std::cin, line);
			options[count] = line;
		}
		//get the answer from the file and load into answer
		std::getline(std::cin, line);
		answer = line;
	}

	void setNewQuestion(std::string theQuestion, int pointValue)
	{
		std::string line;
		questiontype = "MC";
		//get the number of choices from the user
		std::cout << "Enter the number of choices:  ";
		std::getline(std::cin, line);
		numberOfOptions = atoi(line.c_str());

		question = theQuestion;
		value = pointValue;
		//get the individual choice lines and load to options array
		for (int count = 0; count < numberOfOptions; count++) {
			std::cout << "\nEnter next option:  ";
			std::getline(std::cin, line);
			options[count] = line;
		}
		//get the answer from the user and load into answer
		std::cout << "\nEnter Answer:  ";
		std::getline(std::cin, line);
		answer = line;
	}
	void printOptions()// prints the questions, options, and answer
	{
		//char first = 'A';
		std::cout << question << std::endl;
		for (int count = 0; count < numberOfOptions; count++) {
			std::cout << options[count] << "\n";
		}
		std::cout << answer << "\n";
	}

	int getValue() //gets the point value of the question
	{
		return value;
	}

	std::string getQuestionType()// gets the type of question
	{
		return questiontype;
	}

	std::string getAnswer()// prints the answer
	{
		return answer;
	}
};

class Quiz 
{
private:

	questions *myQuestions[10];
	int numquestions;

public:
	int loadQuiz()
	{
		//ifstream infile;
		//string examName = exam;
		std::ifstream infile("quiz.txt");
		std::streambuf *cinbuf = std::cin.rdbuf();       //save old buf
		std::cin.rdbuf(infile.rdbuf());             //redirect std::cin to infile.txt!

		std::string line;
		std::string theQuestion;
		std::string questiontype;
		std::string theAnswer;
		int  questionvalue;

		//get the number of questions from the first line in the file
		std::getline(std::cin, line);
		numquestions = atoi(line.c_str());
		for (int count = 0; count < numquestions; count++) {
			std::getline(std::cin, line);
			//get the next line with the question type and the value of the question
			int npos = line.size();
			int prev_pos = 0;
			int pos = 0;
			while (line[pos] != ' ')
				pos++;
			questiontype = line.substr(prev_pos, pos - prev_pos);
			prev_pos = ++pos;
			questionvalue = atoi(line.substr(prev_pos, npos - prev_pos).c_str()); // Last word

			if (questiontype == "TF")
			{
				myQuestions[count] = new QuestionTF;
				std::getline(std::cin, theQuestion);
				myQuestions[count]->setQuestion(theQuestion, questionvalue);
			}

			if (questiontype == "MC")
			{
				myQuestions[count] = new QuestionMC;
				std::getline(std::cin, theQuestion);
				myQuestions[count]->setQuestion(theQuestion, questionvalue);
			}

		}
		std::cin.rdbuf(cinbuf);   //restore cin to standard input
		return numquestions;
	}

	void displayQuizQuestions(int numquestions)
	{
		std::string qtype;
		//print out the questions that have been processed
		for (int count = 0; count < numquestions; count++)
		{
			qtype = myQuestions[count]->getQuestionType();
			std::cout << qtype << " " << myQuestions[count]->getValue() << "\n";
			myQuestions[count]->printOptions();
			std::cout << "\n";
		}
	}
};

int menu()
{
	int selection = 0;


		std::cout << "Please select an option from the list below." << std::endl;
		//display the menu
		std::cout << "Menu";
		std::cout << "======" << std::endl;
		std::cout << "1 - Load quiz." << std::endl;
		std::cout << "2 - Display quiz." << std::endl;
		std::cout << "3 - Press 3 to exit." << std::endl << std::endl;
		std::cout << "Enter selection: ";
		// read user selection
		//std::cin >> selection;
		while (true)
		{
			std::cin >> selection;
			if (std::cin.fail())
			{
				std::cerr << "Please enter an integer number." << std::endl;
				std::cin.clear();
				std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
			}
			if (selection == 1 || selection == 2 || selection == 3) {
				break;
			}
			std::cout << "The options are: \'1\'\'2\' or \'3\': ";
		}
		std::cin.ignore();
		return selection;
}



int main() 
{

	Quiz theQuiz;
	int numquestions;

	int selection = 0;
	std::string quizName = "quiz.txt";

	while ((selection = menu()) !=3)
	switch (selection)
	{
	case 1:
		std::cout << "You selected - Load quiz." << std::endl;
		numquestions = theQuiz.loadQuiz();
		break;

	case 2:
		std::cout << "You selected - Display quiz." << std::endl;
		theQuiz.displayQuizQuestions(numquestions);
		break;

	case 3:
		break;

		//if  1, 2, or 3 is not selected then go to the default case
	default: std::cout << "Invalid selection. Please try again.\n";
		// no break in the default case
	}
	std::cout << std::endl << std::endl;
	return 0;
}
at a guess, somewhere in there, you have /n instead of \n.
\n in a text string is end of line.
/n in a text string is /n printed.



When I try to run the code you've posted, I get a menu and the only option that does anything is #3. Options #1 and #2 just print "You selected X" and return me to the main menu.
Thanks for the responses. Jonnin I will look to see if I made that mistake anywhere. Helios, the reason option 1 and 2 don't work for you is because don't have the quiz.txt file. I guess I should have posted that as well sorry about that. Here is the quiz.txt file I am using:

6
TF 5
5+5=55?
false
TF 5
11+11=22?
true
TF 10
100*51=5110?
false
MC 10
What is 10*10?
4
10
100
1000
10000
b
MC 5
What is 5+10?
5
6
10
15
20
25
c
MC 10
What is 1000\100?
6
10
100
100
1000
10000
50
a
Hello pleaseINeedHelp,

4, 5, 6 does come out in the load file function, but it only prints the numbers for me. The only thing I can think of is the use of "rdbuff". I do not s any need for "rdbuff" when you can just as easily read the file line by line using "getline".
The 4, 5 and 6 print to the screen during the execution of the for loop on line 208.

I will work with the program after lunch.

Hope that helps,

Andy
Line 122. You are generating output in your setQuestion method.
Line 122: You're doing a cout of NumberOfOptions. This is where 4,5,6 is coming from.

Several observations about your program:

1) Why are variables question, answer, value, and questionType repeated in classes questionTF and questionMC? Since you're using inheritance, you should be using the variables in the base class and not repeating them in the derived classes. You could either make the variables protected so they are accessible in the derived classes (preferred) or use the base class's setters.

2) Why are you redefining cin's streambuf and not just reading directly from infile.

3) You have a memory leak. If you choose option 1 multiple times, the memory for the entries in the myQuestions array is never released. I strongly recommend you use std::vector to hold your questions. Since you're using polymorphic pointers, you will still need to delete the entries in the vector, but at least you won;t overrun the capacity of the vector (see #4).

4) The size of myQuestions array is fixed at 10. You have no check in your program that the number of questions in the file does not exceed 10. Again, the use of std::vector is strongly recommended.

Ahh Thank you everyone for the help. Eliminating line 122 fixed it. AbstractionAnon I have changed the code based on your first observation. The variables in questionTF and questionMC class are now inherited from the questions class. Thanks for that. As for your second opinion on cin's streambuf I'm not sure how to go about changing it. I tried using getline which I got to compile but I got a stdthrow exception and I couldn't figure out why. So as of now that part is still the same. Here is the code I couldn't get to work:
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
class Quiz 
{
private:
	
	//std::vector<std::string> myquestions;
	questions *myQuestions[10];
	int numquestions;

public:
	int loadQuiz()
	{
		//ifstream infile;
		//string examName = exam;
		std::ifstream infile("quiz.txt");
		//std::streambuf *cinbuf = std::cin.rdbuf();       //save old buf
		//std::cin.rdbuf(infile.rdbuf());             //redirect std::cin to infile.txt!

		std::string line;
		std::string theQuestion;
		std::string questiontype;
		std::string theAnswer;
		int  questionvalue;

		//get the number of questions from the first line in the file
		std::getline(infile, line);
		//std::getline(std::cin, line);
		numquestions = atoi(line.c_str());
		for (int count = 0; count < numquestions; count++) {
			std::getline(infile, line);
			//std::getline(std::cin, line);
			//get the next line with the question type and the value of the question
			int npos = line.size();
			int prev_pos = 0;
			int pos = 0;
			while (line[pos] != ' ')
				pos++;
			questiontype = line.substr(prev_pos, pos - prev_pos);
			prev_pos = ++pos;
			questionvalue = atoi(line.substr(prev_pos, npos - prev_pos).c_str()); // Last word

			if (questiontype == "TF")
			{
				myQuestions[count] = new QuestionTF;
				std::getline(infile, line);
				//std::getline(std::cin, theQuestion);
				myQuestions[count]->setQuestion(theQuestion, questionvalue);
			}

			if (questiontype == "MC")
			{
				myQuestions[count] = new QuestionMC;
				std::getline(infile, line);
				//std::getline(std::cin, theQuestion);
				myQuestions[count]->setQuestion(theQuestion, questionvalue);
			}

		}
		//std::cin.rdbuf(cinbuf);   //restore cin to standard input
		return numquestions;
	}

	void displayQuizQuestions(int numquestions)
	{
		std::string qtype;
		//print out the questions that have been processed
		for (int count = 0; count < numquestions; count++)
		{
			qtype = myQuestions[count]->getQuestionType();
			std::cout << qtype << " " << myQuestions[count]->getValue() << "\n";
			myQuestions[count]->printOptions();
			std::cout << "\n";
		}
	}
};


Also I agree a vector would be better and I am looking into it but I haven't learned to much about them yet. So I'm not sure I will be able to implement that right now but I am trying to make it work. As for your last observation on there being no check in the program. I was planning to add all the error checking once I was done making the program do what I need it to do. Thanks for all the help so far. If you have any advice on how to go about changing cin's streambuf that would be greatly appreciated because I can't seem to get it to work but I'll keep at it.
A couple of things jump out at me.

Lines 44-45: In the commented out line, you reading into theQuestion. In the infile version, you're reading into line. Then at line 46, you're passing theQuestion.

Lines 52-53: ditto

One style comment: Why not use constructors to initialize your derived class instances rather than making an explicit call to setQuestion()?
41
42
43
44
    if (questiontype == "TF")
    {  std::getline(infile, theQuestion);
	myQuestions[count] = new QuestionTF (theQuestion, questionvalue);
    }

AbstractionAnon, I'm still new to all of this. I haven't learned how to do what your suggesting yet. I just barely know what I already have. But in any case I will try to do some research on what you suggested and see if I can get it to work. Is there a reason why the way you suggested is better? For example is it less coding, faster compile time or run time. Or is that way just a personal preference? Like I said I am still new to all this so sorry if my question sounds dumb, I am just trying to learn as much as I can. Thanks for all the help so far. Also I have a question about the use of new . New means I am dynamically allocating space right? Or does that not apply to the way it is being used in this case?
Constructors are the preferred way to initialize an object. By initializing an object in the constructor, you are guaranteed that the object is in a known state at the time the object is crated. For instance, what is the contents of 'value' after you created your object via new? Hint: It's undefined.

new means I am dynamically allocating space right?

Correct. new does two things.
1) It allocates space for object from the heap.
2) It calls the object's constructor.
In your case, you have no constructor, so the compiler provides you with a default constructor that instantiates your member variables.

Last edited on
AbstractionAnon, Thanks for all of your help I will keep working on it.
Topic archived. No new replies allowed.