NCurses getstr() 带有可移动光标?

发布于 2024-10-18 20:12:04 字数 118 浏览 0 评论 0原文

我想在 NCurses 中使用 getstr() 读取使用输入。但是,当我使用箭头键时,它会打印键码而不是实际移动光标。如何让它从左向右移动,以便我可以在文本传递到缓冲区之前对其进行编辑?

I want to read use input using getstr() in NCurses. However, when I use the arrow keys, it prints keycodes instead of actually moving the cursor. How can I make it move left of right so I can edit the text before it gets passed into the buffer?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

埋葬我深情 2024-10-25 20:12:04

Curses 不解释输入的箭头键。您得到的唯一结果是,当设置键盘模式时,KEY_LEFT 充当退格键。但幸运的是,编写您自己的 getstr 替代品并不太复杂。以下对我有用:

#include <ctype.h>
#include <string.h>
#include <ncurses.h>

static void
readline(char *buffer, int buflen)
/* Read up to buflen-1 characters into `buffer`.
 * A terminating '\0' character is added after the input.  */
{
  int old_curs = curs_set(1);
  int pos = 0;
  int len = 0;
  int x, y;

  getyx(stdscr, y, x);
  for (;;) {
    int c;

    buffer[len] = ' ';
    mvaddnstr(y, x, buffer, len+1);
    move(y, x+pos);
    c = getch();

    if (c == KEY_ENTER || c == '\n' || c == '\r') {
      break;
    } else if (isprint(c)) {
      if (pos < buflen-1) {
        memmove(buffer+pos+1, buffer+pos, len-pos);
        buffer[pos++] = c;
        len += 1;
      } else {
        beep();
      }
    } else if (c == KEY_LEFT) {
      if (pos > 0) pos -= 1; else beep();
    } else if (c == KEY_RIGHT) {
      if (pos < len) pos += 1; else beep();
    } else if (c == KEY_BACKSPACE) {
      if (pos > 0) {
        memmove(buffer+pos-1, buffer+pos, len-pos);
        pos -= 1;
        len -= 1;
      } else {
        beep();
      }
    } else if (c == KEY_DC) {
      if (pos < len) {
        memmove(buffer+pos, buffer+pos+1, len-pos-1);
        len -= 1;
      } else {
        beep();
      }
    } else {
      beep();
    }
  }
  buffer[len] = '\0';
  if (old_curs != ERR) curs_set(old_curs);
}

为了使其工作,您需要打开键盘移动和 cbreak 模式,并关闭 echo 模式:

cbreak();
noecho();
keypad(stdscr, TRUE);

我希望这会有所帮助,
约亨

Curses does not interpret the arrow keys for input. The only thing you get is that KEY_LEFT serves as a backspace key when keypad mode is set. But luckily it is not too complicated write your own getstr replacement. The following works for me:

#include <ctype.h>
#include <string.h>
#include <ncurses.h>

static void
readline(char *buffer, int buflen)
/* Read up to buflen-1 characters into `buffer`.
 * A terminating '\0' character is added after the input.  */
{
  int old_curs = curs_set(1);
  int pos = 0;
  int len = 0;
  int x, y;

  getyx(stdscr, y, x);
  for (;;) {
    int c;

    buffer[len] = ' ';
    mvaddnstr(y, x, buffer, len+1);
    move(y, x+pos);
    c = getch();

    if (c == KEY_ENTER || c == '\n' || c == '\r') {
      break;
    } else if (isprint(c)) {
      if (pos < buflen-1) {
        memmove(buffer+pos+1, buffer+pos, len-pos);
        buffer[pos++] = c;
        len += 1;
      } else {
        beep();
      }
    } else if (c == KEY_LEFT) {
      if (pos > 0) pos -= 1; else beep();
    } else if (c == KEY_RIGHT) {
      if (pos < len) pos += 1; else beep();
    } else if (c == KEY_BACKSPACE) {
      if (pos > 0) {
        memmove(buffer+pos-1, buffer+pos, len-pos);
        pos -= 1;
        len -= 1;
      } else {
        beep();
      }
    } else if (c == KEY_DC) {
      if (pos < len) {
        memmove(buffer+pos, buffer+pos+1, len-pos-1);
        len -= 1;
      } else {
        beep();
      }
    } else {
      beep();
    }
  }
  buffer[len] = '\0';
  if (old_curs != ERR) curs_set(old_curs);
}

In order for this to work you need to have keypad move and cbreak mode on, and echo mode off:

cbreak();
noecho();
keypad(stdscr, TRUE);

I hope this helps,
Jochen

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文