1

Here is my code. Why the default case is reached when I'm pressing the right keys (arrow up or arrow down). When I run it and press Arrow Up for example, it reaches default case, and then if I press the key another time, is reaching the right case and work. Why is this happening ?

#include <conio.h>
#include <iostream>
#include <windows.h>
using namespace std;

#define KEY_UP 72
#define KEY_DOWN 80
#define KEY_LEFT 75
#define KEY_RIGHT 77
#define KEY_RETURN 13

void admin_login()
{
    system("cls");
    std::string username, password;
    /*gotoxy(console::width/2-10,console::height/2-3);*/
    std::cout << "\nUsername: ";
    std::cin >> username;
    std::cout << "\nPassword: ";
    std::cin >> password;
}

int main()
{
    int c = 0;
    int line = 0;
    std::string menu_line[] = { "Admin login", "Guest login", "Change color theme", "Exit" };

    while(1)
    {
        system("cls");

        for(int i = 0 ; i < 4 ; i++)
        {
            if(i == line)
                SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),12);
            else
                SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),15);

            std::cout << menu_line[i] << '\n';
        }


        switch((c=getch()))
        {
            case KEY_UP:
                 --line;
                 if(line == -1)
                     line = 3;
                 break;
            case KEY_DOWN:
                 ++line;
                 if(line == 4)
                     line = 0;
                 break;
            case KEY_RETURN: 
                 switch(line)
                 {
                     case 0:
                     system("cls");
                     admin_login();
                     break;
                 }
                 break;
             default:
                 cout << endl << "null" << endl;  // not arrow
                 system("pause");
                 break;
        }
}

return 0;
}
  • https://linux.die.net/man/3/getch - "The getch, wgetch, mvgetch and mvwgetch, routines read a character from the window. In no-delay mode, if no input is waiting, the value ERR is returned." Are you getting ERR? Have you printed the numeric value returned to see what it is? – RyanP Jan 03 '17 at 19:25
  • I don't get an error. I think getch is working fine. I think is a problem with the ASCII values. I heard that arrow keys have different ascii values depeding on OS. I don't understand why is reaching the default cause instead of going to right case when I press arrows. – Ioan Rîpan Jan 03 '17 at 19:29
  • I remember having an issue with arrow keys before where it was because they send two bytes to the input instead of just one. Maybe this is the case here and for whatever reason, the getch() is waiting for another keypress to capture the second byte. What do you get if you move `c = getch()` to before the switch and print it out, like `c = getch(); cout << c << endl; switch (c) {...`? – jonhopkins Jan 03 '17 at 19:34
  • I tried this, and the first value is 224, and then when I press the key again it is 80. If this is the problem, how can I solve this ? – Ioan Rîpan Jan 03 '17 at 19:37
  • If it is always 224 for up or down, since it doesn't correspond to any other key, it's probably safe to have a case for it, and in that case do another getch and use that to check for 80 or 72 – jonhopkins Jan 03 '17 at 19:41
  • Related (and maybe duplicate but I'll let someone with more C++ knowledge make that judgment): http://stackoverflow.com/questions/10463201/getch-and-arrow-codes – jonhopkins Jan 03 '17 at 19:42
  • Thank you very much. You're right. I solved the problem. :) – Ioan Rîpan Jan 06 '17 at 00:23

1 Answers1

4
#define KEY_UP 72

        switch((c=getch()))
        {
            case KEY_UP:

72 is the ASCII for uppercase H character.

It is highly unlikely that pressing the cursor-up key on your keyboard types the letter H.

The actual explanation is that a cursor movement keypress generates a multi-character code, most likely an Esc code following by one or two characters, with the last one being H.

On my terminal, for example, cursor-up generates the ESC [ A character sequence.

Your for loop reads a single character at a time. So, naturally, when it reads Esc, this gets handled by the default code path. And, on the next read, (or the following one), H is read, and this is the results you are seeing.

Sam Varshavchik
  • 114,536
  • 5
  • 94
  • 148