«строка чтения», когда вывод идет в начале строки [закрыто]

Я использую (отлично) 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 , за которым следует курсор.

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

  1. Это действительно похоже на ошибку, теперь, когда я понял, это зависит от того, сколько символов набрано в строке, где ошибка. Какие-нибудь исправления / обходные пути?

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

PS Можно ли здесь спросить о программировании readline под Ubuntu, или мне следует публиковать сообщения на stackoverflow.com ?

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

2 ответа

Оказывается, что readline не может распознать, не запускается ли это в столбце № 1, и, таким образом, мешайте себе портить предыдущий вывод на строке.

единственный способ иметь дело с этим состоит в том, чтобы распознать стартовый столбец самостоятельно и переместиться в запуск следующей строки вниз, если текущая позиция не столбец № 1. Затем это будет всегда начинать с крайнего левого столбца, не производя ненужную новую строку, когда это уже будет в столбце № 1.

, Мы можем сделать это для стандарта "Терминал", потому что это понимает escape-последовательность 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
0
ответ дан 8 December 2019 в 07:24

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

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

Так, readline предполагает, что начинает писать в начале терминальной строки. Когда Вы, Ctrl-U (отбрасывание строки Unix), readline возвращается, где это думает, что Вы запустили к символам текста, т.е. сразу после его подсказки. Ваша подсказка "хорошо>" является четырьмя символами долго, таким образом, readline помещают каре в 5-е место и стирают строку, покидая просто "Ад".

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

[обновление]

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

readline может испустить две различных последовательности символов для стирания целого входа:

  • также: n Г — <BS> (клавиша Backspace) + < управляющая последовательность для стирания целого line> (например, ANSI <ESC> [ K), где n является количеством символов, введенных до сих пор.
  • или: <CR> + m Г — < управляющая последовательность для перемещения курсора в right> (например, ANSI <ESC> [ C) + < управляющая последовательность для стирания целого line> где m является продолжительностью подсказки.

readline выбирают самое короткое, которое зависит от количества введенного wrt символов продолжительность Вашей подсказки.

0
ответ дан 8 December 2019 в 07:24

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

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