【问题标题】:How to format a string longer than 99 characters in Lua如何在 Lua 中格式化超过 99 个字符的字符串
【发布时间】:2018-04-27 05:36:11
【问题描述】:

我正在格式化要打印到控制台的字符串,并尝试根据终端大小进行格式化。但是,Lua 似乎不允许任何长度超过 99 个字符的格式。 (source)

在终端大于 100 列宽的情况下,我还能如何填充字符串以使用整行?或者打印一些右对齐的东西?我知道我可以用循环来做数学和填充空格,但这感觉效率低下。还有什么我想念的吗?也许是一些终端控制字符?

更新:我在源中链接了错误的位置。 This 似乎是我要挂断的功能。它只允许 2 位数字来指定字段大小,如第 1087 行所述。

我正在尝试做的一个例子:

每次操作的 X 次迭代,我都会以如下格式打印一行:

"\rDone: %d, Left %d, Current: %s"

这每次都会清除线路以保持状态更新,而不会向控制台发送垃圾邮件。

问题是当字符串 /long-path/to/file-name 被打印为 %s 参数并且下一次迭代打印 /path/to/file 时,前一行的一部分被留下,因为它没有被覆盖较短的线。使用 format 将行填充到控制台的整个宽度可以防止这些“剩余”字符。

【问题讨论】:

  • MAX_ITEM 大约是格式化期间消耗的单个项目的长度。这与结果字符串的实际大小无关。 MAX_ITEM 也是 120 个字符,如该链接中明确指出的那样,而不是 99。
  • 可能是我没有链接到Lua源码的正确位置,我对C的理解不是很好;诚然,我花在阅读此资源上的时间并不多。但是,测试实际的 Lua 代码显示格式“%99s”有效,而“%100s”失败并出现错误“(宽度或精度太长)”。
  • 对,但是"%s" 工作得很好,不管给定字符串中有多少个字符。那么为什么要明确限制字符数呢?
  • 啊,我的标题可能具有误导性。我不是在谈论格式化一个长度超过 99 个字符的字符串,而是应用一个字段长度超过 99 个字符的格式。 “为什么”是一个长度超过 99 个字符的终端行。假设我想提供一些统计数据,然后在该行的右侧放置一个 xx% done 指示器。在其他语言中,我通过使用终端的全宽格式化字符串来做到这一点。它更多的是关于填充而不是限制。
  • Here 是 lstrlib.c 中的函数,其中字段宽度限制为两位数。 (链接到 lua.org 可能更持久。)

标签: lua console


【解决方案1】:

您可以尝试打印一些ANSI Escape Codes。请参阅“光标位置”代码。

由于您不能将控制代码直接写入字符串,您必须使用string.char 生成包含控制代码的字符串。

另一种选择是预先生成所需的每个长度的填充字符串并在以后引用它们:

padding = {}
padding[1] = " "
for i = 2,MAX_PAD do
  padding[i] = padding[i-1].." "
end
-- now padding[i] is a string of i spaces. 

在传递给string.format 之前,将填充字符串与格式字符串的其余部分连接起来。

【讨论】:

  • 我特别不想在循环中连接字符串,但光标位置控制代码确实允许我进行数学运算以右对齐输出。
【解决方案2】:

使用格式将行填充到控制台的整个宽度可以防止这些“剩余”字符。

这样也可以:

local str = string.format("\rDone: %d, Left %d, Current: %s", ...)
if(#str > line_length) then
  str = str .. string.rep(" ", line_length - #str)
end

【讨论】:

  • 不是我打算采用的方式,但我什至没有想过使用 string.rep,感谢您指出。
【解决方案3】:

ESC[2K 控制字符解决了我的大部分问题。该控制代码不是试图用空格覆盖前一行,而是删除整行。这是 VT100 控制代码的不错参考:http://www.termsys.demon.co.uk/vtansi.htm

【讨论】:

    猜你喜欢
    • 2018-02-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-30
    • 2013-09-27
    • 2015-06-22
    • 1970-01-01
    相关资源
    最近更新 更多