如何避免使用 goto 进行一系列提示?

发布于 2024-09-16 08:10:11 字数 251 浏览 4 评论 0原文

我正在编写一个基于控制台的应用程序,提示用户提出一系列问题。例如:

“输入一条要打开的记录:”

“你想做X吗?”

“你想做Y吗?”

“你确定要继续吗?”

如果用户在任何提示下不输入任何内容,我想升一级。使用 goto 很容易做到这一点。我能想到的唯一其他方法是嵌套 for 循环,它看起来丑陋,并且对于多个提示来说变得相当笨拙。一定有一个简单的方法可以做到这一点,但我只是想不到。

I'm writing a console based application that prompts a user for a series of questions. E.g:

"Enter a record to open:"

"Do you want to do X?"

"Do you want to do Y?"

"Are you sure you want to continue?"

If the user enters nothing at any prompt I want to go up one level. This is easy using goto. The only other way I can think of to do it is nested for loops which looks far uglier and gets pretty unwieldy for more than a couple of prompts. There must be an easy way to do this though, I just can't think of it.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

白况 2024-09-23 08:10:11

您基本上正在编写一个非常简单的状态机 - 使用函数来表示每个状态:(我将使用随机伪代码,因为您没有指定语言)

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< 中抽象问题和结果的内存地址/code> 结构:

struct question {
    question *next, *prev;
    char prompt[];
    char **result;
}

然后循环运行,调用 question* run_question(question*),根据答案转到 ->next 或 ->prev,直到结果为 NULL (作为停止条件,当结果被填写并且没有留下任何问题时)。

如果您使用具有直接指针访问的命令式语言,最后一个解决方案可能是最“正常的解决方案”。

You're basically writing a very simple state machine - use functions to represent every state: (I'll use random pseudocode, since you didn't specify a language)

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)

this is a trivial approach. In some languages the call stack will grow, in others it won't. If you have a language which causes the stack to grow, you can use trampolines to prevent it, by rewriting get_information to do:

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))

Or even abstracting the question and memory address of result in some question structure:

struct question {
    question *next, *prev;
    char prompt[];
    char **result;
}

and then running in a loop, calling question* run_question(question*), going to ->next, or ->prev depending on the answer, until the result is NULL (as a stop condition, when results are filled in and no questions are left).

The last solution is probably the most "normal one" if you use an imperative language with direct pointer access.

不交电费瞎发啥光 2024-09-23 08:10:11

递归地而不是迭代地编写它。

Write it recursively instead of iteratively.

亢潮 2024-09-23 08:10:11

将其写为一个简单的状态机。

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;
    }
}

write it as a simple state machine.

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;
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文