Function Keys (F1-F12) Encountered a logic bug

Feb 27, 2014 at 8:22am
Hello again,

I was developing an exercise program for myself (note: not a project in school) to enhance my programming skills in C++ then I encountered a "logic bug" (that's how I call it :D ) I think. I googled stuffs I need to know and ended up to post my question here.

Here's the scene:

1. When using GetAsyncKeyState I can capture Function Keys [F1-F12, etc..]
2. While doing and having fun to my exercise program, I suddenly noticed that whatever key I pressed from the keyboard {example: asdfkj], it keeps the keys entered and brings to a "field" that accepts user input.



What you should do...

1. Press any key (example: asdfisdjfisdjff) then proceed to press F1. And see what happens. I don't know how to erase what I have entered before pressing F1. Hope someone could help me.

Please refer to line #96 - #105 only. TIA

here's the code.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
#include <cstdlib>
#include <iostream>
#include <windows.h>
#include <string>

using namespace std;

void gotoxy();
void gotoxy( int column, int line ) {

  COORD coord;
  coord.X = column;
  coord.Y = line;
  SetConsoleCursorPosition(GetStdHandle( STD_OUTPUT_HANDLE ), coord );
}

void clearstatus();
void clearstatus() {

    for(int x=3;x<=38;x++) {
        gotoxy(x,10); 
        cout << " ";
    }
}

void newstudent();
void newstudent(){

     string in;
     
     for(int x=4;x<=10;x++)
     {
        gotoxy(34,x);
        cout << "|";
        gotoxy(76,x);
        cout << "|";                  
     }
     gotoxy(35,3);
     cout << "---------------NEW STUDENT---------------";
     gotoxy(36,4);
     cout << "Full Name : ";
     gotoxy(36,5);
     cout << "   Course : ";
     gotoxy(36,6);
     cout << "    Level : ";
     gotoxy(36,7);
     cout << " Contact# : ";
     gotoxy(35,8);
     cout << "-----------------------------------------";
     gotoxy(48,4); 
     getline(cin, in);
     gotoxy(48,5); 
     getline(cin, in);
     gotoxy(48,6); 
     getline(cin, in);
     gotoxy(48,7); 
     getline(cin, in);
     
     gotoxy(36,9);
     cout << "Do you want to keep the record? [Y/N]-";
     getline(cin,in);

     gotoxy(80/2-(24/2),18);
     cout << "----CONSOLE MESSAGE----";
     gotoxy(80/2-(24/2),20);
     cout << "-----------------------";
     
     if(in=="y" || in=="Y") {
          gotoxy(80/2-(17/2), 19);
          cout << "RECORD IS SAVED." << endl;
     }
     else if(in=="n" || in=="N") {
          gotoxy(80/2-(22/2), 19);
          cout << "RECORD WAS DISCARDED." << endl;
     }
}

//*********************************
//*********************************

int main(int argc, char *argv[])
{
   start:
   
   gotoxy(3, 4);
   cout << "[F1]--New Student Record";
   gotoxy(3, 5);
   cout << "[F2]--Students Class Schedules";
   gotoxy(3, 6);
   cout << "[F3]--Medical Check-up History";
   gotoxy(3, 7);
   cout << "[F4]--Find Student Record";
   gotoxy(3, 8);
   cout << "[F5]--Quit Program";
   
   while(1)
   {
       if(GetAsyncKeyState(0x70))
       {
           clearstatus();
           gotoxy(3,10);     
           cout << "Status: New Record (F1)" << endl;
           newstudent();
           break;
       }
       else if(GetAsyncKeyState(0x71)) {
           clearstatus();
           gotoxy(3,10); 
           cout << "Status: Class Schedule (F2)" << endl;
       }
       else if(GetAsyncKeyState(0x72)) {
           clearstatus();
           gotoxy(3,10); 
           cout << "F3 was hit" << endl;
       }
       else if(GetAsyncKeyState(0x73)) {
           clearstatus();
           gotoxy(3,10); 
           cout << "F4 was hit" << endl;
       }
       else if(GetAsyncKeyState(0x74)) {
           clearstatus();
           gotoxy(3,10); 
           cout << "F5 was hit" << endl;
       }
       else if(GetAsyncKeyState(0x1B)) {
           clearstatus();
           gotoxy(3,10); 
           cout << "ESC was hit" << endl;
           break;
       }
       else {
           Sleep(10);     
       }
   }
    
        gotoxy(25, 22);
    system("PAUSE");
    
    for(int x=3;x<=38;x++) {
        gotoxy(x,10); 
        cout << " ";
    }
    
    for(int x=4;x<=10;x++) {
            gotoxy(34,x);
            cout << " ";
            gotoxy(76,x);
            cout << " ";                  
         }
         
    for(int x=35;x<=77;x++) {
        for(int y=3;y<=10;y++) {
                gotoxy(x,y);     
                cout << " ";
        }
    }
    
    for(int x=80/2-(32/2);x<=((80/2)-(32/2)+32);x++) {
        for(int y=18;y<=22;y++) {
                gotoxy(x,y);
                cout << " ";
        }
    }
    
    goto start;
    
    return EXIT_SUCCESS;
}
Feb 27, 2014 at 9:06am
Try calling std::cin.sync(); before reading input. The behavior is implementation defined, but on MSVS and mingw gcc it does what you want
Feb 27, 2014 at 10:38am
You're mixing buffered input with reading key states. No big surprise there are issues.

Don't do that. If you must do that, you should probably be tackling it at a different level:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
void newstudent(){

    auto std_in = GetStdHandle(STD_INPUT_HANDLE);
    FlushConsoleInputBuffer(std_in);

    for (int x = 4; x <= 10; x++)
    {
        gotoxy(34, x);
        cout << "|";
        gotoxy(76, x);
        cout << "|";
    }
    gotoxy(35, 3);
    cout << "---------------NEW STUDENT---------------";
    gotoxy(36, 4);
    cout << "Full Name : ";
    gotoxy(36, 5);
    cout << "   Course : ";
    gotoxy(36, 6);
    cout << "    Level : ";
    gotoxy(36, 7);
    cout << " Contact# : ";
    gotoxy(35, 8);
    cout << "-----------------------------------------";
    gotoxy(48, 4);

    char buffer[256];
    DWORD dummy;

    ReadFile(std_in, buffer, 256, &dummy, 0);
    gotoxy(48, 5);
    ReadFile(std_in, buffer, 256, &dummy, 0);

    gotoxy(48, 6);
    ReadFile(std_in, buffer, 256, &dummy, 0);
    gotoxy(48, 7);
    ReadFile(std_in, buffer, 256, &dummy, 0);

    gotoxy(36, 9);
    cout << "Do you want to keep the record? [Y/N]-";
    ReadFile(std_in, buffer, 256, &dummy, 0);

    gotoxy(80 / 2 - (24 / 2), 18);
    cout << "----CONSOLE MESSAGE----";
    gotoxy(80 / 2 - (24 / 2), 20);
    cout << "-----------------------";

    char ch = buffer[0] ;
    if (ch == 'y' || ch == 'Y') {
        gotoxy(80 / 2 - (17 / 2), 19);
        cout << "RECORD IS SAVED." << endl;
    }
    else if (ch == 'n' || ch == 'N') {
        gotoxy(80 / 2 - (22 / 2), 19);
        cout << "RECORD WAS DISCARDED." << endl;
    }
}
Feb 28, 2014 at 12:27am
Hi again..thank you for your input..I tried your code cire.. and here are the result.

auto std_in = GetStdHandle(STD_INPUT_HANDLE);

error1: 28 D:\cplusplus\main.cpp ISO C++ forbids declaration of `std_in' with no type

error2: 28 D:\cplusplus\main.cpp invalid conversion from `void*' to `int'

FlushConsoleInputBuffer(std_in);

error1: 29 D:\cplusplus\main.cpp invalid conversion from `int' to `void*'

ReadFile(std_in, buffer, 256, &dummy, 0);

error1: 55 D:\cplusplus\main.cpp initializing argument 1 of `BOOL ReadFile(void*, void*, DWORD, DWORD*, _OVERLAPPED*)'

FYI: I am using the DevC++ by Bloodshed.. version is 4.9.9.2 for the code you've written.

I also tried the code in VS10.. and it works! :) :)

btw..is there anyway I can make it run in DevC++? Thank you very much, you helped a lot. God bless you. :)
Feb 28, 2014 at 1:02am
IDE doesn't really affect it. The compiler and compiler settings does. Basically you can either enable c++11 -std=c++11 or tell it the data types instead of using auto which is a type deducter. http://www.cplusplus.com/doc/tutorial/variables/

I would assume the type would be something along the lines of HANDLE but I am not positive since I don't use windows api.
Mar 1, 2014 at 1:30pm
My next problem to the above code solution is that how should I
Echo the text to screen from ReadFile since I use getline.. :-( anybody?
Topic archived. No new replies allowed.