This question already has an answer here:
-
getch and arrow codes
11 answers
I want to take input from the user and check if the user gave up arrow key as the input. I have tried getch function but it only allows user to input a character. I want that user may input up/down arrow key or any string containing more than one characters. Later I wish to check if the user gave up/down key as input or some other string.Please help.
If you must insist on not looking here to find your answer...
I tried this but my compiler does not support conio lib so I can't use getch function.
Why do you need to use getch()
? You could just as easily use any other function to get the input and do the work for you.
Secondly I want to be able to input string also so I will have to use some function like fgets()
.
In my example I have used fgets()
if you so desire.
But the problem is fgets()
don't take up arrow as input. Is there any other way I can do this?
When an up-arrow is entered at the terminal, it might look different on each computer. For example, on my computer when I enter an up arrow it looks like this: ^[[A
. However it looks though, fgets()
does take up-arrows as input. As you saw in the linked question:
By pressing one arrow key getch
will push three values into the
buffer:
'\033'
'['
'A', 'B', 'C' or 'D'
'A' for an up-arrow, 'B' for a down-arrow, 'C' if you enter a right-arrow, and 'D' if you enter a left-arrow. In my example I have only handled up-arrows, but it should be easy to adapt the program to detect other arrows as well.
Now on to the example:
#include <stdio.h>
#include <string.h>
#define MAX_STRING_SIZE 100
void flush_input(char userInput[]);
int main(void) {
char input[MAX_STRING_SIZE] = {0};
int i;
int upArrow = 0; //1 if up arrow found, 0 if not found
printf("Enter anything with an up arrow key (or not if you so choose):\n");
fgets(input, sizeof(input), stdin);
flush_input(input);
size_t inputLen = strlen(input);
for (i = 0; i < (int)inputLen; i++) {
if (input[i] == '\33') {
if(input[i+2] == 'A') {
upArrow = 1;
}
}
}
if (upArrow != 0) {
printf("You entered an up arrow somewhere in the input\n");
} else {
printf("You did not enter an up arrow anywhere\n");
}
return 0;
}
void flush_input(char userInput[]) {
if(strchr(userInput, '\n') == NULL) {
/* If there is no new line found in the input, it means the [enter] character
was not read into the input, so fgets() must have truncated the input
therefore it would not put the enter key into the input. The user would
have typed in too much, so we would have to clear the buffer. */
int ch;
while ( (ch = getchar()) != '\n' && ch != EOF );
} else {
//If there is a new line, lets remove it from our input. fgets() did not need to truncate
userInput[strcspn(userInput, "\r\n")] = 0;
}
}
We detect an up arrow by checking if there is a '\033'
(note that with octal codes like this, you do not need the 0 so checking for '\33'
is also valid), and if there is, then we check two characters ahead (to skip the '['
) with if(input[i+2] == 'A')
. If this is true, we know an up arrow key will have been entered.
Let's run some example tests (remember that in my terminal, an up arrow key looks like ^[[A
):
user@user Stack Overflow $ ./a.out
Enter anything with an up arrow key (or not if you so choose):
hello^[[A
You entered an up arrow somewhere in the input
user@user Stack Overflow $ ./a.out
Enter anything with an up arrow key (or not if you so choose):
bye bye
You did not enter an up arrow anywhere
So, in conclusion, I don't know why you thought that the possible duplicate did not work since you couldn't use the getch()
. The function that you use to get the input is completely irrelevant. The only important part in this process is understanding how arrow keys are entered in the terminal.