我目前正在测试我的家庭作业的驱动程序。会发生的是我有一个打印了不同选项的菜单,程序使用基于用户输入的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;
}
答案 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之外。