I'd like to move the cursor forward and backwards in a C program. I'm reading the whole line in a loop, but i would like that if a cursor key gets pressed the cursor on the screen changes position, without blocking the loop. I tried getwch()
but it blocks the caller until enter it's pressed. What i'm looking for is a behavior similar to bash prompt. I'm reading with a code similar to this:
while (TRUE) { printf("%s", PROMPT); fgets(input, 1024, stdin); do_something(input); }
I'm trying that the function above works like readline(PROMPT)
on the readline.h
library
1) A cursor is the position indicator on a computer display screen where a user can enter text. In an operating system with a graphical user interface (GUI), the cursor is also a visible and moving pointer that the user controls with a mouse, touch pad, or similar input device.
The gotoxy() function places the cursor at the desired location on the screen. This means it is possible to change the cursor location on the screen using the gotoxy() function. It is basically used to print text wherever the cursor is moved.
Using termios
and console-codes (VT100 compatible - not portable):
#include <stdio.h> #include <string.h> #include <termios.h> #include <unistd.h> #define cursorforward(x) printf("\033[%dC", (x)) #define cursorbackward(x) printf("\033[%dD", (x)) #define KEY_ESCAPE 0x001b #define KEY_ENTER 0x000a #define KEY_UP 0x0105 #define KEY_DOWN 0x0106 #define KEY_LEFT 0x0107 #define KEY_RIGHT 0x0108 static struct termios term, oterm; static int getch(void); static int kbhit(void); static int kbesc(void); static int kbget(void); static int getch(void) { int c = 0; tcgetattr(0, &oterm); memcpy(&term, &oterm, sizeof(term)); term.c_lflag &= ~(ICANON | ECHO); term.c_cc[VMIN] = 1; term.c_cc[VTIME] = 0; tcsetattr(0, TCSANOW, &term); c = getchar(); tcsetattr(0, TCSANOW, &oterm); return c; } static int kbhit(void) { int c = 0; tcgetattr(0, &oterm); memcpy(&term, &oterm, sizeof(term)); term.c_lflag &= ~(ICANON | ECHO); term.c_cc[VMIN] = 0; term.c_cc[VTIME] = 1; tcsetattr(0, TCSANOW, &term); c = getchar(); tcsetattr(0, TCSANOW, &oterm); if (c != -1) ungetc(c, stdin); return ((c != -1) ? 1 : 0); } static int kbesc(void) { int c; if (!kbhit()) return KEY_ESCAPE; c = getch(); if (c == '[') { switch (getch()) { case 'A': c = KEY_UP; break; case 'B': c = KEY_DOWN; break; case 'C': c = KEY_LEFT; break; case 'D': c = KEY_RIGHT; break; default: c = 0; break; } } else { c = 0; } if (c == 0) while (kbhit()) getch(); return c; } static int kbget(void) { int c; c = getch(); return (c == KEY_ESCAPE) ? kbesc() : c; } int main(void) { int c; while (1) { c = kbget(); if (c == KEY_ENTER || c == KEY_ESCAPE || c == KEY_UP || c == KEY_DOWN) { break; } else if (c == KEY_RIGHT) { cursorbackward(1); } else if (c == KEY_LEFT) { cursorforward(1); } else { putchar(c); } } printf("\n"); return 0; }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With