Hello Tappy,
Earlier I showed you what main should look like. That has not changed.
I will start with the header file that I called "Classes.hpp". I like to put things like classes and prototypes in in a header file. For the most part the classes are OK, but needed some improvement. I will also mention that I put some of the function definitions in s separate .cpp file.
This will give you an idea of what I changed notice the comments:
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
|
#ifndef _CLASSS_
#define _CLASSS_
//question class
class Question
{
protected:
std::string m_question;
int m_points;
public:
Question(std::string theQuestion, int pointValue);
//std::string getQuestion(std::string qu); // <--- Bad format and bad function. Not used.
//int getValue(int val); // Did not use this one either.
virtual ~Question();
void SetQuestion(std::string question); // <--- Added.
void SetPoints(int points); // <--- Added.
// These functions are not needed in this class. They work better in the other two classes.
// virtual std::string printOptions()
// {
// return NULL;
// }
// virtual std::string getAnswer()
// {
// return NULL;
// }
}; //end question class
#endif // end !_CLASSS_
|
The declaration of the dtor is fine his way when it is a base class inherited by another class.
The two set functions should be set up this way and should oly do one thing set the private member variable of the class.
The "Get..." function is the opposite and its only function is to return a private member variable value.
The other two classes are similar except that they only need one "Set..." function and I did not use any "Get..." functions.
In all the classes I changed the private variables to start with "m_" to make it easier to know it is part of a class. I do not know how strict this is but it seems to be a common convention for naming class variables.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
|
void testBank(std::ifstream& infile) // <--- Passed by reference.
{
//declarations
//constexpr int numQuestions{ 3 }; // <--- in the end not needed.
//constexpr int numOptions{ 6 }; // <--- in the end not needed.
// Always initialize your variables when you define the.
int points{ 0 }, numberOfQuestions{ 0 }, numberOfOptions{ 0 };
std::string questionType{ "" }, questionText{ "" }, answerText{ "" }, mcOption{ "" };
//arrays improper definition and not used.
//std::string questionBank[numQuestions] = {}, answerBank[numQuestions] = {}, mcOptions[numOptions] = {};
//class objects
//Question test(questionText, points); // <--- Does not need to be defined here.
QuestionTF tf(questionText, points, answerText); // <--- This defines both QuestionsTF and Questions.
QuestionMC mc(questionText, points, answerText); // <--- This defines both QuestionsMC and Questions.
// <--- Both objects of Question are different.
//read number of questions
//std::ifstream infile; // <--- Duplicate definition of infile. Not needed here.
infile >> numberOfQuestions;
|
Referring to the above code:
Lines 4 and 5 I added to work with line 11 until I realized that none of those variables on line 11 were never used. More importantly you are tying to create an array with a variable that has no value yet and defining an array this way is not allowed. Lines 4 and 5 fixed that problem. If you look at the code on line 11 you are trying to use a variable, e.g., "numQuestions" that does not get a value until line 21.
Line 14 is not needed because "QuestionsTF" and "QuestionsMC" both create an object of "Questions"
line 21 will read from the file the first line which in this case is 3 into "numberOfQuestions" or you could easily use the original "numQuestions".
After this I kept the for loop and most of the original code, but did make chnges. Some are commented out as you can see here others I added.
1 2 3 4 5 6 7 8 9 10 11 12
|
for (int i = 1; i <= numberOfQuestions; i++)
{
infile >> questionType >> points;
std::cout << "Question " << i << ":" << std::endl;
tf.SetPoints(points);
//test.getValue(points);
//test.getQuestion(questionType);
//std::cout << std::endl; // <--- Used in testing as break point.
//true/false
.
.
.
|
I added line 5 because that is the way it should be done.
Lines 6 and 7 are not used because these functions are wrong and there is no reason to "Get" anything here.
In the first if statement:
1 2 3 4 5 6 7 8 9
|
if (questionType == "TF")
{
infile.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); // <--- Requires header file <limits>.
std::getline(infile, questionText);
std::getline(infile, answerText);
.
.
.
|
I added line 3 because of line 3 in the previous bit of code. After reading the point value of the question the "\n" is left in the input buffer and needs to be cleared before a "getline()" otherwise the "getline()" will only read the "\n" from the buffer and not the file.
I will give you a chance to figure out the rest of the if statement.
The If statement for "MC" will start the same way reading the question then it changes to deal the possible answers ending with reading the answer. In between you will have to "Set"the member variables of the classes. I used a for loop to deal with the possible answers. Keep in mind that the array to hold these answers starts at index zero not one. And in your original the condition of the for loop says "<=" this will crash your program when it runs because the last number for a subscript will be 6, as I setup the array to be a size of 6, a 6 as the subscript will put this element outside the upper bound of the array thus crashing the program. The for condition only needs to be "<" to work properly.
This may not be exactly what you want, but when you get this working it would not be that hard to change it around.
I noticed you are using WordPad. Do not use this as it is not a pure ASCII text editor. Notepad would be better, but still not the best. Installing either Visual Studio, I would suggest the 2017 version, or the latest version of Code::Blocks would be the best. If all you want is a simple text editor do a search for "gedit"
There is something to keep you busy for awhile,
Hope that helps,
Andy