在这段代码中
void menu() {
char name[MAXNAME];
float a;
char c;
cout << "n\tnew transaction\n";
cout << "v\tview all transactions\n\n";
c = getchar();
flushbuf();
switch (c) {
case 'N':
case 'n':{
cout << "What is the name? (press 'b' to go back to the menu)\n";
fgets(name, sizeof name, stdin);
replaceTrailingNl(name); // replaces trailing '\n' (from fgets) with '\0'
if (strcasecmp(name, "b") == 0)
menu();
do {
flushbuf();
cout << "What is the amount?\n";
} while (scanf("%f", &a) == 0);
if (writeTransData(name, a))
cout << "Successfully saved!\n";
else
cerr << "writeTransData: Error occurred\n";
break;}
}
}
void flushbuf()
{
int temp;
while ((temp = getchar()) != EOF && temp != '\n') ;
}
当输入“b”作为“名称是什么”提示的答案时,将调用 menu()(显示菜单),显示菜单,然后我按“n”创建一个新的交易。一切都按预期进行,直到 break
。 break
完成后,我再次询问“金额是多少?\n”,我实际上可以向其中输入内容。这是怎么回事?我做错了什么?
最佳答案
再次调用 menu()
不会结束当前对 menu()
的调用。 Call #2 将完成,控制流将返回 Call #1 并进入 do
循环。
最简单的修复是这样的:
if (strcasecmp(name, "b") == 0) {
menu();
return;
}
但是,这是一个糟糕的设计,因为您正在使用递归并无缘无故地用完堆栈。你可以使用 goto
:
void menu() {
char name[MAXNAME];
float a;
char c;
menu_prompt:
cout << "n\tnew transaction\n";
cout << "v\tview all transactions\n\n";
c = getchar();
flushbuf();
switch (c) {
case 'N':
case 'n':{
cout << "What is the name? (press 'b' to go back to the menu)\n";
fgets(name, sizeof name, stdin);
replaceTrailingNl(name);
if (strcasecmp(name, "b") == 0)
goto menu_prompt;
不过,通常情况下,您会使用外部循环进行输入。然后,您将分别使用 continue
和 break
,具体取决于您是否希望用户重试。
关于c++ - 控制流程跳回另一行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28635374/