& Ldquo; Readline & Rdquo; когда есть выход в начале строки [закрыт]

Я использую (отлично) readline (версия 6.3, библиотека по умолчанию [не-vi]) из моей собственной программы, работая в окне терминала (на ПК). Существует проблема, когда предыдущий вывод не завершается новой строкой, когда вызывается 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 (может быть, другие), чтобы удалить ваш вход, пока все кажется хорошо ... readline() перемещает каретку обратно сразу после своего приглашения. Однако попробуйте ввести текст, скажем:

123456 <Ctrl+U>

Теперь он удаляется обратно в Hello, оставляя только Hell на линии, а затем карет.

Мне нужно одно из двух возможных решений:

Это выглядит как ошибка, теперь, когда я понял, что это зависит от того, сколько символов введено в строке, где это происходит неправильно. Любое исправление / обходное решение? В качестве альтернативы, есть ли readline библиотечный вызов, который я мог бы сделать, который скажет мне, в какой позиции / столбце находится карет, прежде чем я вызову readline()? Тогда, по крайней мере, я мог узнать, что я нахожусь в конце существующей строки и вывожу \n, чтобы сначала позиционировать себя в начале новой строки.

P.S. Является ли это подходящим местом, чтобы спросить о программировании readline в Ubuntu или я должен публиковать его на stackoverflow.com?

1
задан 17 December 2016 в 14:07

1 ответ

[Stackoverflow будет более подходящим местом для такого вопроса программирования]

Это не ошибка, а ожидаемое поведение. readline не знает, что было написано на терминале раньше и в какой позиции он пишет. Подумайте «базовый последовательный терминал». Кроме того, другие фоновые процессы (которые ваша программа не знает) могут также записываться на терминал.

Итак, readline предполагает, что он начинает писать в начале строки терминала. Когда вы Ctrl-U (unix-line-discard), readline возвращается туда, где, как вы думаете, вы начали вводить символы, т. Е. Сразу после его подсказки. Ваше приглашение «ОК>» имеет длину четыре символа, поэтому readline помещает каретку на 5-е место и стирает строку, оставляя только «ад».

Обходным путем может быть пропустить строку перед вызовом readline, или для начала вашего запроса с символом CR (т.е. \r), который заставит приглашение в начале строки переписать «Hello» (но более длинный текст будет только частично перезаписан).

[d4 ] [update]

Что касается того, почему иногда Ctrl-U стирает только последние введенные символы, а иногда и стирает (почти) всю строку, это оптимизация readline.

readline может испускать две различные последовательности символов, чтобы стереть весь вход:

либо: n × <BS> (backspace) + & lt; управляющая последовательность для стирания всей строки & gt; (например, ANSI <ESC> [ K), где n - количество символов, введенных до сих пор. или: <CR> + m × & lt; управляющая последовательность для перемещения курсора вправо & gt; (например, ANSI <ESC> [ C) + & lt; управляющая последовательность для стирания всей строки & gt ;, где m - длина подсказки.

readline выбирает кратчайший, который зависит от количества символов, набранных по длине вашего приглашения.

0
ответ дан 23 May 2018 в 03:16
  • 1
    Я думаю , что вы не принимаете во внимание поведение пользователя (попробуйте мою программу). Если вы набираете до 5 символов и после этого строка readline удаляет и возвращает 5 символов; если вы наберете 6 символов, он удалит и вернется на 6 + 6 == 12 символов. Если readline требует предположения, что он будет вызываться только в начале терминальной линии (до любого приглашения), почему он не говорит так где-то? – JonBrave 17 December 2016 в 16:20
  • 2
    @JBarchan Я добавил объяснение этого поведения к моему ответу. – xhienne 17 December 2016 в 17:31
  • 3
    Думаю, я согласен с сутью вашего объяснения двух способов readline сделать стирание. (Но вашего # 2 недостаточно: там нет стирания, только перемещение курсора, должен быть дополнительный выход erase-to-EOL?) Если бы я мог заставить его всегда выбирать обратную прокрутку, которая решите: есть ли способ, который я могу сказать, чтобы выбрать это, или что мой терминал не может сделать ваш # 2? – JonBrave 17 December 2016 в 20:21
  • 4
    @JBarchan Хорошо поймать, я исправил свой ответ. Извините, я не знаю, достаточно ли читать, чтобы ответить на ваш последний вопрос. Я не думаю, что изменение определения termcap могло бы решить эту проблему. Возможно, один из многочисленных вариантов readline. – xhienne 17 December 2016 в 20:40
  • 5
    @JBarchan Есть ли что-то в моем ответе, что вы все еще недовольны, и что от него не следует выбирать или, по крайней мере, голосовать за него? – xhienne 19 December 2016 в 22:27

Другие вопросы по тегам:

Похожие вопросы: