I intend to develop a command line tool by C in the CentOS, with the following code:
// 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;
}
The program can works, but it doesn't execute the way I expect it to when I press the arrow keys.
I have finished typing a simple SQL and now the cursor stays after the semicolon.
[root@olap tests]# gcc client.c
[root@olap tests]# ./a.out
cli > selectt * from table_001;
But I misspelled the first keyword, it should be select
, not selectt
.
I am now pressing the left arrow key(←) to try to fix this mistake.
But the cursor didn't move properly as I expected, and it turned into the following.
[root@olap tests]# gcc client.c
[root@olap tests]# ./a.out
cli > selectt * from table_001;^[[D^[[D^[[D^[[D^[[D^[[D^[[D
How should I modify the program to solve this problem?
I hope get help from people who are good at C development.
Thank you all
CodePudding user response:
You might want to try the ncurses library with getch
This sample code demonstrates how you can detect arrow keys and have a CLI prompt:
#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;
}
CodePudding user response:
Consider using the readline
library, you can find it here. It supports arrow keys, a input history and input of any length (if configured).
char *input = readline("cli >");
if (input)
{
if (strcmp(command, "exit\n") == 0)
...
free(input);
}