문제

I am currently testing out my driver program for my homework. What happens is that I have a menu printed with different options, and the program uses a switch statement based on the user's input to determine what to do. Everything works fine except for the "exit program" case, where it's supposed to leave the program and end it. Instead, it will print out the message "Quitting program" (like it's supposed to) and then follow up with doing one of the first 4 cases. It doesn't actually leave the switch statement. I don't know what could be wrong because I've used this method before and have not encountered this issue.

#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;
}
도움이 되었습니까?

해결책

The root cause of your problem is that your code uses recursion instead of iteration.

main makes a call to action, which goes into a switch, which then calls action again, which goes into the switch and calls action, until the Quit option is selected.

At this point the recursive call chain starts to unwind. Unfortunately, since your code lacks break statements, the switch is not exited immediately. Instead, the code falls through to the next case label, making you think that the return did not do its job at terminating the action. It did, but only the last action on the call stack is terminated. The remaining ones are still in progress, so they would continue as soon as the higher-level action finishes.

You can add break statements to your switch statement to mask the problem. However, the root cause would not go away: your program would remain poorly organized, and hard to read.

Consider rewriting the code using a while loop in the action function. Keep the switch, add breaks, and remove recursive calls to action from inside the switch. Instead, let the loop continue, so that the switch is re-entered and processed again, until the Quit option is selected.

다른 팁

First thing you do is call action(books, 0); to get to the menu.

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

There you call action(books, option); with the user supplied number.

You continue doing this for every option untill the user enters a 5 to end the program. Because you don't have any break statements the code will go back to the 'calling case' and continue executing into the next case.

Be sure to end a case with a break to not continue executing the next case block (fall through).

Here is another questionn about why a break is needed.

In main() you call action(book, 0) so it enters action function. Then you prompt for choice and enter action() gain with that option. Then you enter 5 and quit that action, the return address of the nested action() call returns just after that call, at case 1: block and continues to execute it.

So what you need to do is put break statement at the end of each block.

When you don't use break after once case block, the code continues executing next case block.

So as the guy above said, you should consider placing break at the end of each block.

Also, you might want to consider not using recursion, but maybe iteration, and put prompt block outside the switch/case.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top