我正在通过this site学习Lua。我在教程的最开始,我正在尝试这个程序(输入一个数字,x
,它返回x!
):
-- defines a factorial function
function fact (n)
if n == 0 then
return 1
else
return n * fact(n-1)
end
end
print("enter a number:")
a = io.read("*number") -- read a number
print(fact(a))
然而,当我运行它时,io.read
似乎出现在提示之前。我在Notepad ++控制台中运行它,如下所示:
"C:\Program Files\Lua\5.1\lua.exe" "Path\To\factorial.lua"
输出(看似)是空白但如果我输入一个数字,则该功能会运行。
5
enter a number:
120
虽然这不是一个很大的问题,但我只能想象在创建之前使用的变量所带来的问题。那么,如何让这个程序在读取输入之前提示输入数字呢?
答案 0 :(得分:13)
发生的事情并不是代码运行不正常,而是提示没有立即显示给终端。
在内部,您输出的任何内容都由操作系统存储在IO缓冲区中。缓冲区定期清空,其内容显示在终端上(刷新)。在大多数系统上,默认情况下终端是行缓冲,这意味着每次你写一个行尾字符 - print()
自动执行 - 它会被刷新;但是,在某些系统上,它默认为完全缓冲,这意味着它只在填满时自动刷新。
有两种方法可以解决这个问题。如果要为文件上的所有 IO操作禁用或更改缓冲(为了这些目的,终端计为文件),您可以使用file:setvbuf()
功能;特别是,io.output():setvbuf("no")
将禁用标准输出的缓冲,这意味着您编写的任何内容都将立即显示。您还可以使用io.output():setvbuf("line")
在支持但不支持默认值的系统上启用行缓冲。
另一种方法是手动刷新缓冲区,这在您希望立即显示某个特定输出但不希望通用禁用输出缓冲时非常有用。您可以使用file:flush()
函数执行此操作,该函数会立即刷新缓冲区,例如:
-- no newline, so even on line-buffered systems this may not
-- display immediately
io.write("Enter a number: ")
-- so we force it to
io.flush()
请注意,io.write()
和io.flush()
只是io.output():write()
和io.output():flush()
的便捷功能,即获取当前输出文件,然后调用:write()
或{ {1}}。{/ p>
(为什么要干扰缓冲?因为它更快 - 将数据写入终端或文件是昂贵的,写一个大东西比写很多小东西要快。在大多数情况下,无论如何事情不会在代码运行的瞬间被写入,因此操作系统会将数据保存在缓冲区中,然后在缓冲区填满时进行一次大写操作。)