【问题标题】:C++ Switch Statment Exception HandlingC++ Switch 语句异常处理
【发布时间】:2019-09-07 21:25:11
【问题描述】:

我正在尝试在我的 switch 语句中为 memnu 编写异常处理代码,以防用户输入非 int 的内容。尝试了许多不同的方法,当用户输入字符时仍然会出现连续循环。

我尝试过使用 std 异常,但即使使用包含,我的编译器在构建期间仍然会看到错误。

#include <iostream>
#include <string>
#include <fstream>
#include <cstdlib>
#include <cctype>

using namespace std;

class Exam

{

public:

    int loadExam()
    {

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

        string line, theQuestion, questiontype, theAnswer;
        int  questionvalue;

        //get the number of questions from the first line in the file
        getline(cin,line);
        numquestions = atoi(line.c_str());
        for(int count = 0; count < numquestions; count++){

            getline(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

            //process a true/false question
            if (questiontype == "TF")
            {

                myQuestions[count] = new QuestionTF;
                getline(cin,theQuestion);
                myQuestions[count]->setQuestion(theQuestion,questionvalue);

            }

            //process a multiple choice question
            if (questiontype == "MC")
            {

                myQuestions[count] = new QuestionMC;
                getline(cin,theQuestion);
                myQuestions[count]->setQuestion(theQuestion,questionvalue);

            }
        }

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

    }

    void displayExamQuestions(int numquestions)
    {

        string qtype;

        //print out the questions that have been processed
        for(int count = 0; count<numquestions;count++)

        {

            qtype = myQuestions[count]->getQuestionType();
            cout << qtype << " " << myQuestions[count]->getValue() << "\n";
            myQuestions[count]->printOptions();
            cout << "\n";

        }
    }

private:

    Question *myQuestions[10];
    int numquestions;

};

int main() {

    Exam myExam;
    int numquestions;
    int choice;

    while((choice = displayMenu())!=3)

        switch(choice)
        {
            case 1:
                numquestions = myExam.loadExam();
                break;

            case 2:
                myExam.displayExamQuestions(numquestions);
                break;

            default:
                cout << "Invalid choice.  Try again.\n\n";

        }

   getchar();
    return 0;

}

int displayMenu()
{

    int choice;

    cout << "\t===================== Exam Menu =====================" << endl;
    cout << "\t1.  Load Exam "<<endl;
    cout << "\t2.  Display Exam "<<endl;
    cout << "\t3.  Quit"<<endl;
    cout << "\t=====================================================" << "\n" << endl;
    cout << "Please enter your selection: ";
    cin >> choice;
    cout << "\n" << endl;

    return choice;

}

当用户输入一个字符或一串字母字符时,要求输出读取“无效选择,请重试”。

【问题讨论】:

  • 异常到底是什么意思?你对std::exception 有什么期望?
  • 不要使用开关。不要使用异常来处理输入错误。不要编写基于控制台的菜单。测试文件是否打开,如果没有则报告错误。测试每个输入函数的返回值。换句话说,不要像你写的那样写代码。
  • 如果您遇到编译器错误,请在此处复制并粘贴。如果您遇到运行时错误,请添加您的输入、程序的输出和预期输出。
  • 可能重复(如果我理解正确的话):stackoverflow.com/questions/26187729/…

标签: c++ exception switch-statement


【解决方案1】:

在这种情况下,验证应该由 displayMenu 函数处理,原因有两个。

  1. displayMenu 函数表示它将返回一个整数,因此它应该负责确保用户输入的是数字,而不是字符或字符串。

  2. displayMenu 列出了选项,因此它知道有多少选项可用,这意味着它还应该检查整数是否在 1 和 3 之间。

Infinite loop with cin when typing string while a number is expected

    int displayMenu() //This function should be responsible for validating that an 
                      // int was inputed
    {
        int choice;

        while (true)
        {
            cout << "\t===================== Exam Menu =====================" << endl;
            cout << "\t1.  Load Exam " << endl;
            cout << "\t2.  Display Exam " << endl;
            cout << "\t3.  Quit" << endl;
            cout << "\t=====================================================" << "\n" << endl;
            cout << "Please enter your selection: ";
            cin >> choice;
            cout << "\n" << endl;

            if (cin.fail())
            {
                cin.clear();
                cin.ignore(numeric_limits<streamsize>::max(), '\n'); //This clears out the stream if they entered a string
                //Try using cin.ignore() and inputing a string to see what happens.
            }
            else if (choice >= 1 && choice <= 3)
            {
                break;
            }
        }

        return choice;
    }

您可以通过一个简单地打印菜单的 displayMenu 函数和一个不关心输入什么整数的名为 getInput 的第二个函数来解耦第二部分。然后由调用函数来确保该值在 1 和 3 之间。

#include <iostream>
#include <string>
#include <fstream>
#include <cstdlib>
#include <cctype>

using namespace std;

void displayMenu();
int getInput();

int main() {

    int numquestions;
    int choice = 0;

    while (choice != 3)
    {
        displayMenu();
        while ((choice = getInput()) < 1 || choice > 3) 
        {
            std::cout << "Please pick a value between 1 and 3\n";

            displayMenu();
        }

        switch (choice)
        {
        case 1:
            cout << "Case 1\n";
            break;

        case 2:
            cout << "Case 2\n";
            break;

        default:
            cout << "Invalid choice.  Try again.\n\n";
        }
    }

    getchar();
    return 0;

}

//Only responsible for getting an int
int getInput()
{
    int choice;

    while (true)
    {
        cin >> choice;
        cout << "\n" << endl;

        if (cin.fail())
        {
            cin.clear();
            cin.ignore(numeric_limits<streamsize>::max(), '\n');

            std::cout << "Please enter a valid number\n";
        }
        else
        {
            break;
        }
    }

    return choice;
}

//This function only displays a menu
void displayMenu()
{
    cout << "\t===================== Exam Menu =====================" << endl;
    cout << "\t1.  Load Exam " << endl;
    cout << "\t2.  Display Exam " << endl;
    cout << "\t3.  Quit" << endl;
    cout << "\t=====================================================" << "\n" << endl;
    cout << "Please enter your selection: ";
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-02
    • 1970-01-01
    相关资源
    最近更新 更多