我正在编写一个基于控制台的应用程序,它会提示用户提出一系列问题。例如:
“输入要打开的记录:”
“你想做X吗?”
“你想做Y吗?”
“你确定你要继续吗?”
如果用户在任何提示下都没有输入任何内容,我想上一层。这很容易使用 goto。我能想到的唯一另一种方法是嵌套 for 循环,它看起来更丑陋,并且对于多个提示变得非常笨拙。必须有一个简单的方法来做到这一点,但我只是想不出。
我正在编写一个基于控制台的应用程序,它会提示用户提出一系列问题。例如:
“输入要打开的记录:”
“你想做X吗?”
“你想做Y吗?”
“你确定你要继续吗?”
如果用户在任何提示下都没有输入任何内容,我想上一层。这很容易使用 goto。我能想到的唯一另一种方法是嵌套 for 循环,它看起来更丑陋,并且对于多个提示变得非常笨拙。必须有一个简单的方法来做到这一点,但我只是想不出。
您基本上是在编写一个非常简单的状态机 - 使用函数来表示每个状态:(我将使用随机伪代码,因为您没有指定语言)
get_information():
return get_record()
ask_record():
record = read_line()
return () if !record
return ask_y(record)
ask_x(record):
x = read_line()
return ask_record() if !x
return ask_y(record, x)
ask_y(record, x):
y = read_line()
return ask_x(record) if !y
return ask_continue(record, x, y)
ask_continue(record, x, y)
continue = read_line()
return ask_y(record, x) if !continue
return (record, x, y)
这是一种微不足道的方法。在某些语言中,调用堆栈会增长,而在其他语言中则不会。如果你有一种语言会导致堆栈增长,你可以使用蹦床来防止它,通过重写get_information
来做:
x = get_information
while x is function:
x=x()
return x
ask_x(record):
x = read_line()
return (lambda: ask_record()) if !x
return (lambda: ask_y(record, x))
甚至将结果的问题和内存地址抽象为某种question
结构:
struct question {
question *next, *prev;
char prompt[];
char **result;
}
然后在一个循环中运行,question* run_question(question*)
根据答案调用,转到 ->next 或 ->prev,直到结果为 NULL(作为停止条件,当结果被填写且没有问题时)。
如果您使用具有直接指针访问的命令式语言,最后一个解决方案可能是最“正常的”。
递归地而不是迭代地编写它。
把它写成一个简单的状态机。
while(running)
{
if (state == INIT)
{
out("enter record");
state = DO_X;
}
else if (state == DO_X)
{
do whatever for x.
state = WHATEVER_NEXT_STATE_IS;
}
}