2016-12-17 76 views
3

我在我自己的程序中使用readline(版本6.3,默认[non-vi]模式,Ubuntu 14.04)库,在终端窗口中运行(在PC )。当调用readline()时,如果先前的输出未被换行符终止,则会出现问题。当在行首输出时出现“readline”

#include <stdio.h> 
#include <readline/readline.h> 

void main(void) 
{ 
    // Previous output from some other part of application 
    // which *may* have output stuff *not* terminated with a '\n' 
    printf("Hello "); 
    fflush(stdout); 

    char *in = readline("OK> "); 
} 

所以行的样子:

Hello OK> <caret here> 

如果你键入一个小数目的字符(?最多5人),然后,比如说,Ctrl+U(可能是其他公司)删除您的输入,因此远非如此--将脱字符号移回到它自己的提示符之后,即删除5个字符。然而,尝试打字,说:

123456 <Ctrl+U> 

现在它删除回Hello,只留下Hell上线,随后插入符号,即删除6 + 6 = = 12。所以你看:

Hello OK> 123456 <Ctrl+U> 
Hell<caret here> 

我需要的两种可能的解决方案之一:

  1. 我已经意识到这取决于有多少个字符在哪里出了问题的线类型。任何修复/解决方法?

  2. 另外,有没有一个readline库调用我可以做,它会告诉我什么位置/列脱字符是在我调用readline()之前?那么至少我可以认识到,我处于现有生产线的末端,并输出一个\n,以便让我自己定位于一条新生产线的开始。

我想我可以排序的猜测长达5个字符键入它高达5退格,但在它选择做其它的事情,如果它没有在行从头开始这打乱了?

我看到GNU Readline: how to clear the input line?。这是一样的情况吗?解决方案看起来相当复杂。在启动readline()时,是不是可以问清楚你在哪一栏,或者告诉它在删除时不要那么聪明,坚持只删除实际输入的字符数量?

+0

你能与readline的7.0再次检查?刚刚安装它(它默认为这个最新版本),并且不能复制这个。 – usr2564301

+1

哦!我是Ubuntu的新手。我正在使用安装了14.04 LTS的版本6,并执行了'sudo apt-get install libreadline-dev',它也做了6,现在说'libreadline-dev已经是最新版本了。对不起,我该如何取得/升级到7? – JonBrave

+0

对不起,我在Mac上有它自己特有的安装软件包的方式 - 我使用brew进行下载,并自动选择最新的源代码。你有足够的信心尝试手动下载和构建?您也可以找到最近的更新日志,并检查是否有相关的事情已被注意到。 – usr2564301

回答

3

事实证明,readline无法识别它是否不是从列#1开始,从而停止自己搞乱上一行的输出。

解决此问题的唯一方法是自行识别起始列,如果当前位置为而不是列#1,则移至下一行的起始位置。然后它总是从最左边的列开始,而不是在列1已经输出不必要的换行符。

我们可以为标准的“终端”这样做是因为它知道一个ANSI转义序列来查询终端的当前行&列。查询通过字符发送到stdout,并通过终端插入stdin的字符读取响应。我们必须将终端置于“原始”输入模式,以便可以立即读取响应字符并且不会被回显。

所以这里是代码:

rl_prep_terminal(1);  // put the terminal into "raw" mode 
fputs("\033[6n", stdout); // <ESC>[6n is ANSI sequence to query terminal position 
int row, col;    // terminal will reply with <ESC>[<row>;<col>R 
fscanf(stdin, "\033[%d;%dR", &row, &col); 
rl_deprep_terminal();  // restore terminal "cooked" mode 
if (col > 1)    // if beyond the first column... 
    fputc('\n', stdout);  // output '\n' to move to start of next line 

in = readline(prompt);  // now we can invoke readline() with our prompt 
相关问题