centos 如何在C语言标准输入中正确支持箭头键(↑↓←→)?

hpcdzsge  于 2022-11-07  发布在  其他
关注(0)|答案(2)|浏览(139)

我打算在CentOS中用C语言开发一个命令行工具,代码如下:

// client.c

# include <stdio.h>

# include <stdlib.h>

# include <string.h>

# include <unistd.h>

# include <termios.h>

int main(int argc, char *argv[])
{
    char command[128];

    while (1)
    {
        memset(command, 0, 128);
        printf("cli > ");
        if (fgets(command, 128, stdin) != NULL)
        {
            if (strcmp(command, "exit\n") == 0)
                break;
            if (strcmp(command, "\n") == 0)
                continue;
            printf("do something ... %s", command);
        }
    }

    return 0;
}

程序可以工作,但当我按下箭头键时,它没有按我期望的方式执行。
我已经输入了一个简单的SQL,现在光标停留在分号后面。

[root@olap tests]# gcc client.c 
[root@olap tests]# ./a.out 
cli > selectt * from table_001;

但是我拼错了第一个关键字,应该是select,而不是selectt。我现在按左箭头键(←)试图纠正这个错误。但是光标并没有像我预期的那样正确移动,它变成了下面的样子。

[root@olap tests]# gcc client.c 
[root@olap tests]# ./a.out 
cli > selectt * from table_001;^[[D^[[D^[[D^[[D^[[D^[[D^[[D

我应该如何修改程序来解决这个问题?
我希望能得到擅长C语言开发的人的帮助。
谢谢大家

6psbrbz9

6psbrbz91#

您可能需要尝试使用getch的ncurses
此示例代码演示了如何检测箭头键并显示CLI提示符:


# include <string.h>

# include <ncurses.h>

int main(int argc, char *argv[])
{
  int ch,i;
  char command[128];

  initscr();
  clear();
  noecho();
  cbreak();
  keypad(stdscr, true);

  while (1) {
      printw("cli> ");
      for (i=0;;i++) {
          ch=getch();

          if (ch==KEY_UP||ch==KEY_LEFT||ch==KEY_RIGHT||ch==KEY_DOWN) {
              /* printw("arrow keys pressed!");
              command[i]='\0';
              break; */
              i--;
          }
          else if (ch=='\n') {
              if (i>0)
                  printw("\n");
              command[i]='\0';
              break;
          }
          else {
              command[i]=ch;
              printw("%c",ch);
          }
      }
      if (strcmp(command, "exit") == 0)
          break;
      else
          printw("%s\n", command);

    }
    endwin();

    return 0;
}
f45qwnt8

f45qwnt82#

考虑使用readline库,你可以找到它here。它支持箭头键,输入历史和任何长度的输入(如果配置)。

char *input = readline("cli >");
if (input)
{
    if (strcmp(command, "exit\n") == 0)
    ...
    free(input);
}

相关问题