这里是一个程序,应该加载一些测验,允许进行测验,然后显示结果。我已经重新编写了代码,并狂热地检查了语法错误,但是似乎无法弄清楚为什么它不能正确加载文本文件。我还在Dev C ++和VS代码之间切换,以查看是否可以解决问题,唯一的区别是VS代码给了我一个错误代码-有所不同。在本文发布时,我正在使用Dev C ++。
尽管我确实取得了突破,但是我能够加载文本文件,但问题未正确加载。
具有正确格式的文本文件的内容:
1
TF
5
6 is equal to 3+3
true
从问题的数量开始,然后是问题的类型TF =是/否,然后是问题的点值,然后是问题,然后是答案。
此已加载,但没有问题(请参见下面的屏幕截图)。
我尝试添加更多问题并遵循上述格式,但又回到了原来的问题。
代码
/*This program consists of a menu that allows users to load questions to a vector, then display them to the screen. */
#include <iostream>
#include <iomanip>
#include <string>
#include <fstream>
#include <cstdlib>
#include <vector>
#include <stdexcept>
using namespace std;
class Question // super class
{
private:
string question, questiontype;
string answer;
string options;
int points;
public:
virtual string getQuestion() //gets the question
{
return question;
}
virtual int getValue() //gets the point value of the question
{
return points;
}
virtual void setQuestion(string answer, int points)
{
}
virtual void getOptions()
{
}
virtual string getAnswer()
{
return answer;
}
};
class TFQuestion : public Question// class for true and false questions
{
private:
string question, questiontype;
string answer;
int points;
public:
string getQuestion() //gets the question
{
return question;
}
int getValue() //gets the point value of the question
{
return points;
}
//function to read lines in a file to create new object
void setQuestion(string theQuestion, int pointValue)
{
string theAnswer;
question = theQuestion;
points = pointValue;
getline(cin, theAnswer);
answer = theAnswer;
}
void getOptions() //prints the options for that question
{
cout << "True or False" << endl;
}
string getAnswer() //outputs the answer for that question
{
return answer;
}
};
class MCQuestion : public Question //class for multiple choice
{
private:
int numberOfOptions;
string question;
string options[6];
string answer;
int points;
public:
string getQuestion()
{
return question;
}
int getValue() //gets the point value of the question
{
return points;
}
//function to read lines in a file to create new object
void setQuestion(string theQuestion, int pointValue)
{
string line;
getline(cin, line);
numberOfOptions = stoi(line);
question = theQuestion;
points = pointValue;
//get the individual choice lines and load to options array
for (int count = 0; count < numberOfOptions; count++) {
getline(cin, line);
options[count] = line;
}
//get the answer from the file
getline(cin, line);
answer = line;
}
void getOptions() // gets the options
{
char first = 'A';
for (int count = 0; count < numberOfOptions; count++)
{
cout << first++ << ". " << options[count] << "\n";
}
}
string getAnswer()// prints the answer
{
return answer;
}
};
class Exam //class for exams
{
private:
vector <Question*> myQuestions; //creates new vector to hold Question objects
int numquestions;
public:
int loadExam(ifstream& fin) //function to read file contents and store objects in the vector
{
myQuestions.clear();
string line, theQuestion, questiontype, theAnswer;
int questionvalue;
streambuf* cinbuf = cin.rdbuf(); //save old buf
cin.rdbuf(fin.rdbuf()); //redirect std::cin to file
//get the number of questions from the first line in the file
getline(cin, line);
numquestions = stoi(line);
for (int count = 0; count < numquestions; count++)
{
getline(cin, line);
questiontype = line;
getline(cin, line);
questionvalue = stoi(line);
if (questiontype == "TF")
{
myQuestions.push_back(new TFQuestion); //add new TFQuestion to the vector
getline(cin, theQuestion);
myQuestions[count]->setQuestion(theQuestion, questionvalue);
}
if (questiontype == "MC")
{
myQuestions.push_back(new MCQuestion); //add new MC question to the vector
getline(cin, theQuestion);
myQuestions[count]->setQuestion(theQuestion, questionvalue);
}
}
cin.rdbuf(cinbuf); //restore cin to standard input
return myQuestions.size(); //returns vector size to validate data properly added.
}
//function to display each question for the user
void displayExamQuestion(int i)
{
cout << "Question # " << (i + 1) << endl;
cout << myQuestions[i]->getQuestion() << endl;
myQuestions[i]->getOptions();
}
int getNumberOfQuestions()
{
return myQuestions.size();
}
string getCorrectAnswer(int i)
{
return myQuestions[i]->getAnswer();
}
int getPointsValue(int i)
{
return myQuestions[i]->getValue();
}
};
class Student
{
private:
int pointsPossible;
int pointsEarned;
public:
Student()
{
pointsPossible = 0;
pointsEarned = 0;
}
int getPointsPossible()
{
return pointsPossible;
}
int getPointsEarned()
{
return pointsEarned;
}
void setPointsPossible(int points)
{
pointsPossible = points;
}
void setPointsEarned(int points)
{
pointsEarned = points;
}
};
//Function prototypes
string ConvertToupper(string);
int displayMenu();
int main()
{
Exam myExam;
Student s;
/*initialize numquestions variable to zero helps with data validation. Number should change
if loadExam function is successful.*/
int numquestions = 0;
int choice;
try
{ //loop to be executed until user chooses option 4 to quit the program
while ((choice = displayMenu()) != 4)
switch (choice)
{
case 1: //execute when load exam is chosen
{
string file;
cout << "Enter the name of the file you would like to load questions from: ";
cin >> file;
ifstream fin;
fin.open(file.c_str());
while (!fin)
{
cout << "Error. File not found. Try again." << endl;
cout << "Enter the name of the file including the extension (i.e. 'test.txt'): " << endl;
cin >> file;
fin.open(file.c_str());
}
numquestions = myExam.loadExam(fin);
cout << "Success! Number of questions loaded: " << numquestions << endl; //inform user of number of questions loaded
fin.close();
system("PAUSE");
}
break;
case 2: //execute when display exam is chosen.
if (numquestions == 0) //this would indicate no questions are loaded
{
cout << "No questions to display. Questions might not have been loaded." << endl;
system("PAUSE");
}
else //executes as long as there are questions loaded in the vector
{
for (int i = 0; i < myExam.getNumberOfQuestions(); i++)
{
system("CLS"); //clear the screen for each new question
int pts = myExam.getPointsValue(i); //variable to be used for points possible and earned
s.setPointsPossible(s.getPointsPossible() + pts); //add to the total possible points
myExam.displayExamQuestion(i);
cout << endl << "Please enter your answer : ";
string answer;
cin >> answer;
//convert user input and correct answer to ensure proper capitalization
answer = ConvertToupper(answer);
string corrAnswer = ConvertToupper(myExam.getCorrectAnswer(i));
cout << "Correct answer is: " << corrAnswer << endl;
if (answer == corrAnswer) //output if user answers correctly
{
cout << "Correct! Good job!" << endl;
s.setPointsEarned(s.getPointsEarned() + pts); //add points value to points earned
}
else //output if user answers incorrectly
{
cout << "That is incorrect." << endl;
}
system("PAUSE");
}
cout << endl << "You have completed the exam!" << endl; //informs user they have reached end of exam
system("PAUSE");
}
break;
case 3: //displays user exam results
{
try
{ //obtain and convert points earned and points possible to double and calculate percentage
double totalScore = ((double)s.getPointsEarned() / (double)s.getPointsPossible()) * 100.0;
if ((s.getPointsPossible() == 0) && (s.getPointsEarned() == 0))
{
cout << "No results to display. You need to take an exam first." << endl;
system("PAUSE");
}
else
{
cout << "Total points possible: " << s.getPointsPossible() << endl;
cout << "Total points earned: " << s.getPointsEarned() << endl;
cout << "Final Score: " << fixed << setprecision(0) << totalScore << "% " << endl;
system("PAUSE");
}
}
catch (runtime_error& e) //in the event of a divide by zero exception occurs
{
cout << "An exception occurred: " << e.what() << endl;
}
break;
}
default: cout << "Invalid choice. Try again.\n";
}
}
catch (...) //if any exception occurs while running the program
{
cout << "Your choice caused an issue. Check your code. " << endl;
}
cout << "Thank you!" << endl;
getchar();
return 0;
}
string ConvertToupper(string s) //converts only the first character of a string to uppercase
{
string str = s;
str[0] = toupper(str[0]);
return str;
}
int displayMenu() //menu function
{
int choice;
system("CLS"); //clears the screen to make it easier to read for users
cout << "Enter your choice for this Exam." << endl;
cout << "1. Load Exam " << endl;
cout << "2. Take Exam " << endl;
cout << "3. Display Exam Results " << endl;
cout << "4. Quit" << endl;
cin >> choice;
return choice;
}
问题出在文本文件中。光标必须落在每行的最后一个字符上。如果光标不落在加载文件时每行的最后一个字符上。程序将不会加载文件或出现运行时错误。
我不确定为什么从技术角度来看会导致错误。