我的switch语句没有干净地退出循环

时间:2014-05-06 17:08:10

标签: c++ loops switch-statement

我目前正在测试我的家庭作业的驱动程序。会发生的是我有一个打印了不同选项的菜单,程序使用基于用户输入的switch语句来确定要做什么。一切正常,除了“退出程序”的情况,它应该离开程序并结束它。相反,它会打印出“退出程序”的消息(就像它应该的那样)然后跟进前4个案例中的一个。它实际上并没有留下switch语句。我不知道什么是错的,因为我之前使用过这种方法并且没有遇到过这个问题。

#include <iostream>
#include <fstream>
#include <cstring>
#include <string>
#include "ListRecords.h"
#include "BookRecord.h"

using namespace std;

//Prints the menu for the user.
void printMenu(){
    cout << "\n\n1) Insert a book record into the list\n";
    cout << "2) Print information of a book with the given ISBN number\n";
    cout << "3) Print the list of books, sorted by ISBN (lowest to highest)\n";
    cout << "4) Print the list of books, sorted by title\n";
    cout << "5) Quit the program\n";
    cout << "Option: ";
}

//Menu block of the code. Takes in command choice and performs appropriate functions
void action(ListRecords books, int x){
    cin.sync();
    int option;
    switch (x){
        case 0: {
            printMenu();
            cin >> option;
            action(books, option);
                }
        case 1: {
            string title, author, pub;
            long isbn;
            cout << "\n\t**Inserting a new book into the record**";
            cout << "\nTitle: ";
            getline(cin, title);
            cout << "Author: ";
            getline(cin, author);
            cout << "Publisher: ";
            getline(cin, pub);
            cout << "ISBN: ";
            cin >> isbn;
            BookRecord sample = BookRecord(title, author, pub, isbn);
            books.insertBookInfo(sample);
            cout << "\n\tNew book has been entered into the record\n\n";
            printMenu();
            cin >> option;
            action(books, option);
                }
        case 2: {
            long printISBN;
            cout << "Printing book with ISBN number: ";
            cin >> printISBN;
            books.printBookInfo(printISBN);
            cout << "\n\n";
            printMenu();
            cin >> option;
            action(books, option);
                }
        case 3: {
            cout << "\n\t**Printing all books in ISBN increasing order**\n";
            //books.quickSortNum(0, books.seeFillSize());
            books.rearrangeList(0);
            books.printAll();
            printMenu();
            cin >> option;
            action(books, option);
                }
        case 4: {
            cout << "\n\t**Printing all books in alphabetical order**\n";
            //books.quickSortNum(0, books.seeFillSize());
            books.rearrangeList(1);
            books.printAll();
            printMenu();
            cin >> option;
            action(books, option);
                }
        case 5: {
            cout << "\n\t**Quitting program. . .**\n";
            return;
                }
//For the purposes of debugging, I placed option 6 to print all books
        case 6: {
            books.printAll();
            printMenu();
            cin >> option;
            action(books, option);
                }
        default:    {
            cout << "\n\t**ERROR: Invalid input. Try again**\nEnter option: ";
            cin >> option;
            action(books, option);
                    }

    }
}

int main(void){
    string fileName;
    int option;
//Prompt for file name
    cout << "Enter the name of the file: ";
    cin >> fileName;
    cout << "\nLoading the file and its contents. . .";
//Create a List Records object and clear stream
    ListRecords books = ListRecords(fileName);
    cin.sync();     
    cout << "\n\n";
//Start menu process. Beginning option is 0
    action(books, 0);
//Once user quits, this will happen
    cout << "\n Thanks for trying out this program!\n";
    system("pause");
    return 0;
}

3 个答案:

答案 0 :(得分:4)

问题的根本原因是您的代码使用递归而不是迭代。

main拨打action,进入switch,然后再次拨打action,进入switch并致电action {1}},直到选中退出选项。

此时递归调用链开始展开。很遗憾,由于您的代码缺少break语句,因此switch不会立即退出。相反,代码会转到下一个case标签,让您认为return在终止action时没有完成任务。它确实如此,但只有调用堆栈上的最后一个操作才会终止。其余的仍然在进行中,所以一旦更高级别的行动结束,他们就会继续。

您可以在break语句中添加switch语句来掩盖问题。然而,根本原因不会消失:你的程序组织仍然很差,难以阅读。

考虑使用while函数中的action循环重写代码。保留switch,添加break,并从交换机内删除对action的递归调用。相反,让循环继续,以便重新输入switch并再次处理,直到选择退出选项。

答案 1 :(得分:1)

您要做的第一件事是致电action(books, 0);进入菜单。

switch (x){
    case 0: {
    printMenu();
    cin >> option;
    action(books, option);
}

您使用用户提供的号码呼叫action(books, option);

您继续为每个选项执行此操作,直到用户输入5结束程序。 由于您没有任何break语句,因此代码将返回到“调用案例”中。并继续执行下一个case

请务必以休息时间case结束,以便不再继续执行下一个case阻止(通过)。

这是关于为什么需要休息的另一个question n。

答案 2 :(得分:0)

在main()中,您调用action(book, 0),以便进入动作功能。然后提示您选择并使用该选项输入action()获得。然后输入5并退出该操作,嵌套action()调用的返回地址在该调用之后返回,在case 1:block并继续执行它。

所以你需要做的是在每个块的末尾添加break语句。

如果在一次阻止后不使用break,代码将继续执行下一个案例块。

正如上面提到的那样,你应该考虑在每个街区的末尾放置break

另外,您可能要考虑不使用递归,但可能需要迭代,并将提示块放在switch / case之外。