覆盖写入控制台

时间:2015-08-09 15:09:42

标签: c++ linux

我想实现以下目标: 我有一个生成文件的程序,如果具有给定名称的文件已经存在,它应该打印警告,询问用户是否应该覆盖它。它看起来如下:

Processing file                     test.sdf
Checking SDF file...                [OK]
Parsing SDF...                      [OK]
Generating NDDL model file...       [WARN]
Warning. The file "/home/chris/models/test-model.nddl" already exists. Overwrite? [y/N] 

现在,如果用户决定要做什么,我想将控制台光标倒回到[的{​​{1}}字符,并用[WARN][OK]覆盖它,然后使用程序的下一个输出覆盖以下行。

我发现我可以通过ANSI控制序列实现这一目标。由于我只是使用Ubuntu,我可以使用它。

我提出了两个想法:

1)回放光标,直到找到字符串[FAIL],然后再开始写入。

2)逐行向上移动光标,直到移除[WARN]行,并用例如Generating NDDL model file... [WARN]覆盖它。

但是对于这两种方法我都有一个问题,我无法解决或找到一种谷歌搜索方式...

问题1):我无法弄清楚如何读取当前光标位置的字符。但无论如何,我不认为这是个好主意。它似乎并不可靠。

问题2):由于输入文件的路径可以是任意的,我无法控制Generating NDDL model file... [FAIL]出现后打印的行数,所以我只是不知道我应该运行[WARN]多少(ANSI控制序列用于移动光标一行和清除所有内容)。另外,我不知道终端窗口的宽度有多大,所以我也无法计算它(不知道这是不是一个好主意......)

我确信必须有办法实现这一目标,但我无法找到一个良好可靠的方法来实现这一目标......

你们有没有想法?我感谢各种帮助

2 个答案:

答案 0 :(得分:3)

X / Y问题

如果你坚持直接操纵控制台,为什么不完全回到最后两行呢?为什么在重新打印整个内容时尝试编辑一行。此外,您无法保证能够在平台和shell之间以相同的方式操作每个控制台。

您正在打印线路,您应该很容易知道要备份和覆盖的数量。如果你不能这样做,只需清除屏幕并再次将所有内容写回来。

解决方案

呈现这样的界面的正确方法是使用curses库(或等效的)并完全控制输出到控制台。这让你完全掌控。

如果您认为这是 overkill ,那么您注定要在某个时间重新创建public function rules() { return [ 'sid' => function ($input) { // some custom validation logic. } ]; } public function messages() { return [ 'sid' => "Invalid SID!", ]; } 的功能,并最终导致混乱。

答案 1 :(得分:0)

嗯,有一些使用回车符(\ r)的可能性,它会带你到当前行的开头,或者使用退格键(\ b),这将退回一个字符位置然后你只是不得不再写一遍。没有诅咒。没有ANSI疯狂。