【问题标题】:How do I do "io.read" twice on one variable after inputting the wrong type?输入错误类型后,如何对一个变量执行两次“io.read”?
【发布时间】:2019-07-09 06:48:35
【问题描述】:

嘿嘿。我对 Lua 很陌生(尽管我用 Java 编写代码),所以我对此一无所知。我基本上是在尝试获取用户的输入,如果类型不正确,则重新启动。现在,我不确定是 Lua 还是我的 IDE(如果有帮助,我正在使用 ZeroBrane Studio),但无论出于何种原因,它都不会重新输入。 (它只是循环,这意味着它跳过了 io.read 行)

::restart::
...
a = io.read("*number")
if unit == nil then
  print("Error! Incorrect Input!\nRestarting...")
  goto restart
end

哦,是的,我正在使用 goto 命令重新启动。我认为这可能是导致问题的原因,但我也尝试过:

a = io.read("*number") --input non-number
print(a)               --prints
a = io.read("*number") --skips
print(a)               --prints

当你输入一个数字时,它不会跳过。

任何帮助都会很好。提前致谢。

【问题讨论】:

  • 请不要使用“goto”巫毒...
  • 如果有更好/更简单的重启方式,我很乐意使用它。

标签: lua


【解决方案1】:

nvm 我自己解决了

local a
repeat
  a = io.read(); a = tonumber(a)
  if not a then
    print("Incorrect Input!\n(Try using only numbers)")
  end
until a

【讨论】:

  • 这是一个非常好的解决方案。但我将其拆分为自己的函数的建议仍然有效。
【解决方案2】:

不要使用io.read() 的内置过滤器(我认为有时会出现错误),您应该考虑使用自己的小函数来确保用户提供正确的数据。

这是一个这样的功能:

function --[[ any ]] GetUserInput(--[[ string ]] expectedType, --[[ string ]] errorText)
  local --[[ bool ]] needInput = true
  local --[[ any ]] input = nil

  while needInput do
    input = GetData()

    if ( type(input) == expectedType ) then
      needInput = false
    else
      print(errorText)
    end
  end

  return input

end

然后你可以调用它:

local userInput = GetUserInput("number", "Error: Incorrect Input! Please give a number.")

哦,顺便说一句:Goto 被认为是不好的做法。

【讨论】:

  • 这段代码不符合 Lua 语法。是伪代码吗?
  • 它应该可以...也许我犯了一个错误,我不能在这里测试它atm
  • @EgorSkriptunoff 你是对的,代码是错误的。我现在修好了
【解决方案3】:
::restart::
local a = io.read("*n", "*l")
if a == nil then
   io.read("*l")  -- skip the erroneous input line
   print("Error! Incorrect Input!\nRestarting...")
   goto restart
end

附言
随时使用goto 使您的代码更易于理解。
例如,在此代码中使用 whilerepeat-until 循环不会使其变得更好(您需要额外的局部变量或 break 语句)。

【讨论】:

  • 这个答案鼓励(尤其是初学者)使用不良做法,因此应该避免。循环需要额外的控制变量,但更不容易出错且更稳健。
  • @Mischa - 为什么您认为goto 是一种不好的做法,而有时它可能有用?请展示你将如何在没有goto 的情况下重写我的代码,以便代码变得更好。虽然您没有这样的示例,但您的建议(始终避免 gotos)应被视为基于意见(并且不适合 SO)。
  • goto 是一个应谨慎使用的“工具”。在 op 的情况下,当他稍后只想检查另一个用户输入时会发生什么?如果任何输入之一失败,他会重新启动整个过程吗? 1) 假设用户必须输入 10 多个不同的值(有时是文本,有时是数字)并且他不小心搞砸了第 11 个输入......如果我不得不再次做所有事情,我会很生气。 | 2) 他必须为每个输入重复验证码 | 3) 如果他后来决定不复制和粘贴验证代码,他无论如何都必须使它成为一个函数......所以最好在第一次就做好。
  • @Mischa - 我同意有时(但并非总是) goto 是“坏事”。这个任务呢?如果没有goto,你能重写我的代码让它变得更好吗?
  • @Mischa 很抱歉回复晚了,但我使用的代码从一开始就只有 1-3 个输入。如果我想让它更加用户友好,我会返回而不是重新启动。至于验证码,我可以很容易地制作一个函数。复制和粘贴并不难。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多