patterncppMinor
Ask the user random questions from a multiple-choice test
Viewed 0 times
randomtheuseraskquestionschoicetestmultiplefrom
Problem
I'm quite new to programming and was hoping you wouldn't mind taking a look at my code and giving some points as to how I could clean it up.
Assignment guidelines:
Create a program that reads multiple choice questions from 1 file and
gives 10 random questions to the user. Do Not uses classes.
Example of how the questions are stored in the text document I created
Code I used:
```
#include
#include
#include
#include
using namespace std;
struct questionFormat
{
string question;
string answersA;
string answersB;
string answersC;
string answersD;
string answerSheet;
string space;
};
int main ()
{
questionFormat q;
string questions [20];
string answersA [20];
string answersB [20];
string answersC [20];
string answersD [20];
string answerSheet [20];
string space[20];
int userAnswer [10];
int testQuestions [10] = {99,99,99,99,99,99,99,99,99,99};
int counter = 0, num = 0, userCorrect =0, correctAnswer = 0;
fstream infile("testQuestions.txt", ios::in);
srand(time(NULL));
do
{
getline (infile, q.question);
questions[counter] = q.question;
getline (infile, q.answersA);
answersA[counter] = q.answersA;
getline (infile, q.answersB);
answersB[counter] = q.answersB;
getline (infile, q.answersC);
answersC[counter] = q.answersC;
getline (infile, q.answersD);
answersD[counter] = q.answersD;
getline (infile, q.answerSheet);
answerSheet[counter] = q.answerSheet;
getline (infile, q.space);
space[counter] = q.space;
counter++;
} while (counter > userAnswer[counter];
correctAnswer = stoi(answ
Assignment guidelines:
Create a program that reads multiple choice questions from 1 file and
gives 10 random questions to the user. Do Not uses classes.
Example of how the questions are stored in the text document I created
- Question (end of line)
- Option1 (end of line)
- Option2 (end of line)
- Option3 (end of line)
- Option4 (end of line)
- Answer (end of line)
- (intentionally left blank)
- Question2...Question20 (rinse and repeat for remaining questions)
Code I used:
```
#include
#include
#include
#include
using namespace std;
struct questionFormat
{
string question;
string answersA;
string answersB;
string answersC;
string answersD;
string answerSheet;
string space;
};
int main ()
{
questionFormat q;
string questions [20];
string answersA [20];
string answersB [20];
string answersC [20];
string answersD [20];
string answerSheet [20];
string space[20];
int userAnswer [10];
int testQuestions [10] = {99,99,99,99,99,99,99,99,99,99};
int counter = 0, num = 0, userCorrect =0, correctAnswer = 0;
fstream infile("testQuestions.txt", ios::in);
srand(time(NULL));
do
{
getline (infile, q.question);
questions[counter] = q.question;
getline (infile, q.answersA);
answersA[counter] = q.answersA;
getline (infile, q.answersB);
answersB[counter] = q.answersB;
getline (infile, q.answersC);
answersC[counter] = q.answersC;
getline (infile, q.answersD);
answersD[counter] = q.answersD;
getline (infile, q.answerSheet);
answerSheet[counter] = q.answerSheet;
getline (infile, q.space);
space[counter] = q.space;
counter++;
} while (counter > userAnswer[counter];
correctAnswer = stoi(answ
Solution
Cleanup
Use an array of
The lines
can be replaced by
Create function for reading data
Create function
Don't assume file IO succeeded
Always check status of file IO operations. It's never safe to assume that they succeeded.
Change the lines that read the input to:
Simplify the
The line
can be simplified to:
Move the code to conduct the tests to a separate function
The contents of
That will simplify
No need to use an array for
The value is read and used inside every iteration of the loop. It can be a simple
Here's the complete program:
questionFormat- You don't need the
spacevariable.
- The variables
answersA, etc. should beanswerA, etc.
- The type of
answerSheetcan beint. I also think thatcorrectAnsweris a better name for the member.
struct questionFormat
{
string question;
string answerA;
string answerB;
string answerC;
string answerD;
int correctAnswer;
};Use an array of
questionFormat instead of many arrays of stringsThe lines
string questions [20];
string answersA [20];
string answersB [20];
string answersC [20];
string answersD [20];
string answerSheet [20];
string space[20];can be replaced by
questionFormat questions[20];Create function for reading data
Create function
readData and move the code to read the data from main to readData.int readData(std::string const& inputFile,
questionFormat questions[],
int maxQuestions)
{
fstream infile("testQuestions.txt", ios::in);
...
}Don't assume file IO succeeded
Always check status of file IO operations. It's never safe to assume that they succeeded.
Change the lines that read the input to:
for (counter = 0; counter > q.correctAnswer ) )
{
std::cout ::max(), '\n');
infile.ignore(std::numeric_limits::max(), '\n');
}Simplify the
find lineThe line
if (bool exists = find(begin(testQuestions), end(testQuestions), num) != end(testQuestions))can be simplified to:
if (find(begin(testQuestions), end(testQuestions), num) != end(testQuestions))Move the code to conduct the tests to a separate function
void conductTests(questionFormat questions[],
int maxQuestions)
{
...
}The contents of
conductTests will be different from your posted code due to use of an array of questionFormat to hold the data.That will simplify
main to:int main ()
{
questionFormat questions[20];
srand(time(NULL));
int numQuestions = readData("testQuestions.txt", questions, 20);
conductTests(questions, numQuestions);
return 0;
}No need to use an array for
userAnswerThe value is read and used inside every iteration of the loop. It can be a simple
int. Not only that, it can be in the scope of the while loop instead of being in the function scope.Here's the complete program:
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
struct questionFormat
{
string question;
string answerA;
string answerB;
string answerC;
string answerD;
int correctAnswer;
};
int readData(std::string const& inputFile,
questionFormat questions[],
int maxQuestions)
{
fstream infile("testQuestions.txt", ios::in);
for (int counter = 0; counter ::max(), '\n');
infile.ignore(std::numeric_limits::max(), '\n');
}
return maxQuestions;
}
void conductTests(questionFormat questions[],
int maxQuestions)
{
int testQuestions [10] = {99,99,99,99,99,99,99,99,99,99};
int counter = 0;
int userCorrect = 0;
cout > userAnswer;
if (userAnswer == questions[num].correctAnswer)
{
userCorrect++;
}
counter++;
}
}
cout << "You got a total of " << userCorrect << " out of 10 correct" << endl;
}
int main ()
{
questionFormat questions[20];
srand(time(NULL));
int numQuestions readData("testQuestions.txt", questions, 20);
conductTests(questions, numQuestions);
return 0;
}Code Snippets
struct questionFormat
{
string question;
string answerA;
string answerB;
string answerC;
string answerD;
int correctAnswer;
};string questions [20];
string answersA [20];
string answersB [20];
string answersC [20];
string answersD [20];
string answerSheet [20];
string space[20];questionFormat questions[20];int readData(std::string const& inputFile,
questionFormat questions[],
int maxQuestions)
{
fstream infile("testQuestions.txt", ios::in);
...
}for (counter = 0; counter < maxQuestions; ++counter )
{
questionFormat& q = questions[counter];
if ( !getline (infile, q.question) )
{
std::cout << "Failed to read a question.\n";
return counter;
}
if ( !getline (infile, q.answerA) )
{
std::cout << "Failed to read answer A to a question.\n";
return counter;
}
if ( !getline (infile, q.answerB) )
{
std::cout << "Failed to read answer B to a question.\n";
return counter;
}
if ( !getline (infile, q.answerC) )
{
std::cout << "Failed to read answer C to a question.\n";
return counter;
}
if ( !getline (infile, q.answerD) )
{
std::cout << "Failed to read answer D to a question.\n";
return counter;
}
if ( !(infile >> q.correctAnswer ) )
{
std::cout << "Failed to read the correct answer to a question.\n";
return;
}
// Ignore two lines of text.
// The first line corresponds to what's left in the stream
// after reading the correct answer.
// The second line is the intentionally left space.
infile.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
infile.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
}Context
StackExchange Code Review Q#141115, answer score: 7
Revisions (0)
No revisions yet.