user2990606
user2990606

Reputation:

getchar() in a do while loop

I'm trying to write a program that uses the arrow keys to choose an option and than select it with the enter key. The problem is, and i've researched this, is that getchar() needs a (second) enter keystroke to choose the option. I haven't found a solution to my problem while researching this. Here's (part of) the code:

        .....
        system("/bin/stty --file=/dev/tty -icanon");
        ch = getchar();
        switch (ch) {
            case 66:  // up arrow
                value += 1;
                if (value > numOptions-1) { value = numOptions-1; }
                break;
            case 65:  // down arrow
                value -= 1;
                if (value < 0) { value = 0; }
                break;
        }
    } while (ch != 13);      // Our termination cond: then hit enter.

....
const char *options2[]={"option1", "option2", "option3", "option4"};
const char *selected2[]={"OPTION1", "OPTION2", "OPTION3", "OPTION4"};
....

Ok. I finally solved this. Apparently, a text file was causing the program to somehow not parse the carriage return properly. Getchar does work, after all. Thanks everyone for your help.

Upvotes: 0

Views: 915

Answers (3)

gabrieljcs
gabrieljcs

Reputation: 675

I'd recommend the ncurses library.

From this neat ncurses guide:

No echoing. If you have called noecho(), the character ch will not be printed on the screen, otherwise it will. Disabling automatic echoing gives you more control over the user interface.

No buffering. If you have called cbreak(void) each key the user hits is returned immediately by getch(). Otherwise the keys hit by the user are queued until a newline is read. Then calls to getch() take characters from the queue in FIFO manner until the queue is empty and the next whole line is read.

Special keys. If you have called keypad(stdstr, TRUE), then if the user hits a special key such as the Delete key, the arrow keys, Ctrl combined keys and function keys, a single int value will be returned. [...] To use these keys, you need to check the return value of getch(). For example:

    int ch = getch();
    switch (ch) {
         case KEY_BACKSPACE: /* user pressed backspace */ 
            ...
         case KEY_UP:  /* user pressed up arrow key */
            ...
         case KEY_DOWN:  /* user pressed up arrow key */
            ...
         case 'A' ....   /* user pressed key 'A' */
            ...
    }

Reading the neat guide mentioned above should give all the insight you'll need; but if you have any doubts, don't hesitate on asking.

Upvotes: 1

Rahul
Rahul

Reputation: 3509

Instead of using getchar(), getch() should be used. Since getchar() accept the char after hitting the enter key.

Upvotes: 2

Yabada
Yabada

Reputation: 1758

You could do a manual read of one char on the input.

psedo code :

int main(){
   char buf;
   int fd = open(0, READ); // can't remember if open input is necessary 
   while (read(fd, buf, 1)) {
      doStuff(buf);
   }
}

Also, you might want to do a non blocking read. This way each keypress will be sent to your program :

int flags = fcntl(fd, F_GETFL, 0);
fcntl(fd, F_SETFL, flags | O_NONBLOCK);

Upvotes: 0

Related Questions