Thread: Problems with cin and GetAsyncKeyState

  1. #1
    Registered User
    Join Date
    Aug 2008
    Posts
    30

    Problems with cin and GetAsyncKeyState

    Well, I'm a beginner in C++ and I tend to make MANY errors when trying out codes I'm not taught before. So recently I got to know about GetAsyncKeyState and i used it in my main function which is basically a menu. I did all the stuff I will need to do for GetAsyncKeyState in a bool keyDown(int vKey) function which returns either 1 or 0 depending on whether the key is pressed.

    Now my menu is supposed to link to another file which takes care of the user entering his/her profile. For this page I used cin, but I noticed a bug. This bug is that if I type something on the menu then press Enter to go into the profile page, which would go to the void profile() function, whatever I typed while on the menu page would automatically cin into my first cin, which is very weird. Of course, it would be better if someone could add me on MSN and help me but [if you need to see a part of my code to find out whats causing this problem feel free to post it here.]

  2. #2
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    I don't do MSN, but I will try to help you here.
    GetAsyncKeyState doesn't "consume" the keys that it returns as being used. You may want to use the FAQ to get the code for "how do I read input without waiting for the user" (In level 2 "How Do I ..."). That will consume the input.

    However, if you want to use cin, you'd better not use Windows API functions intermingled with that.

    [Of course, another option would be to count the number of keys detected with GetAsyncKeyState, and then use cin.ignore(count), but if you don't scan for EVERY key on the keyboard, you potentially will miss some - so I'd still recommend that you use a different method for reading the keyboard].

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  3. #3
    Registered User
    Join Date
    Aug 2008
    Posts
    30
    Well basically what I meant was that the bool keyDown(int vKey) function would check if a key is pressed. So lets say keyDown(VK_RETURN) would check if VK_RETURN is pressed. So lets say I do something like

    Code:
    if(keyDown(VK_RETURN))
    {
         cout << "Enter!" << endl;
    }
    the keyDown function would return true if I pressed Enter and then cout Enter right? But now the problem is the string I want the user to cin after the user is done with the menu.

    Like
    Code:
    struct profile
    {
         string name;
    };
    void profilepage(void)
    {
         system("cls");
         profile player;
         cout << "Enter your name :";
         cin >> player.name;
    void main (void)
    {
         cout << "This is the Menu! Press Enter to proceed!" << endl;
         if(keyDown(VK_RETURN))
         {
              profilepage();
         }
    }
    So if the player presses Enter, he'll go to the "Enter your name :" part right? But the bug now is that, if I press Enter, it would show "Enter you name :" but the blinking _ is on the next line. I found it weird so at the "This is the Menu! Press Enter to proceed!" part I typed lolol before pressing Enter and the moment I press Enter it shows "Enter you name : lolol". Why does this happen? O_O and please remember that I am still a newbie so xD

  4. #4
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Yes, so did you just skim through my reply without paying attention: GetAsyncKeyState() only tells you whether that key is pressed. If you press the key, a character is entered into the input buffer. That is what cin reads. GetAsyncKeyState does not use up the keypresses, it just reports if that key is pressed at the exact moment in time or not.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  5. #5
    Registered User
    Join Date
    Aug 2008
    Posts
    30
    Well I admit I skimmed through but it was because I didn't get the "consume" part so I thought I had to make things as clear as possible. So anyway, are you talking about the cin buffer thing which cin.clear() clears? and whenever I type anything it would go into the cin buffer?

  6. #6
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Yes, I'm talking about [1] the buffer that cin uses. But cin.clear() does not empty that buffer. cin.ignore(19999) will remove anything up to the next newline (as long as it's less than 19999 characters).

    And by consume, I mean that GetAsyncKeyState does not "use up" any keypresses, the keys you hit will go into the cin buffer as you type, and then be used by cin >> player.name. Try typing in "Charlie" before hitting enter on the main menu, and you would see that palyer.name becomes "Charlie".


    [1] Technically, cin doesn't get any data until enter is pressed, but for all intents and purposes we can ignore that. I'm just saying this to avoid someone commenting that this is incorrect.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  7. #7
    Registered User
    Join Date
    Aug 2008
    Posts
    30
    Try typing in "Charlie" before hitting enter on the main menu, and you would see that palyer.name becomes "Charlie".
    Yep this is THE bug. How do I fix this? put cin.ignore(19999) somewhere properly in the void profile(void) function?

  8. #8
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by In Post #2
    You may want to use the FAQ to get the code for "how do I read input without waiting for the user" (In level 2 "How Do I ..."). That will consume the input.
    .

    That would consume the characters, and I _THINK_ it will be safe.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  9. #9
    Registered User
    Join Date
    Aug 2008
    Posts
    30
    @_@ A bunch of codes I don't understand. Lol. Umm...char pword[BUFSIZ];
    BUFSIZ? What exactly is BUFSIZ? I don't see it anywhere else in the code -_-

  10. #10
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    BUFSIZ is defined by stdio.h and is the size of the FILE * buffers - it's just "some arbitrarily large number that we can expect the user to not exceed when typing". You can replace it with for example 100 or 500 if you like.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  11. #11
    Registered User
    Join Date
    Aug 2008
    Posts
    30
    Ahh OK. I'll try it out to see if I can fix my problem. By the way, how can I get you if I can't get other stuff or can't solve my current problem. This thread? Create another thread? xD Thanks for the help.

  12. #12
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    You should not try to "get me", you should post in a thread here - there are many other skilled people on the forum. Whether you post in this thread or a new one depends on how close the question is to the current thread. If it's not related, then a new thread is the correct thing.

    You can also try to search the forum before you ask a new question.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  13. #13
    Registered User
    Join Date
    Aug 2008
    Posts
    30
    Ok suprisingly I solved the cin buffer thing. I added a cin.ignore(50,'\n') for it to work. Somehow, cin.ignore() and cin.ignore(50) doesn't work. Anyway, now I have a problem where if the user press Enter without keying in anything for "Enter Name :" an endless loop of the next cout would occur. "Enter Name:"'s variable is a string.

  14. #14
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    By default, ignore ignores until the EOF.

    As to your question, who knows what you did? (Answer: you, and not us.) What is the loop condition on your infinite loop?

  15. #15
    Registered User
    Join Date
    Aug 2008
    Posts
    30
    That endless loop is something like THE endless loop that happens when say you cin a char into an int variable. But if you need to see the code,
    Here it is!
    Code:
    struct personProfile
    {
    	char name[50];
    	int age;
    	char gender;
    };
    void profile (void)
    {
    	int choice;
    	personProfile person1;
    	
    	system("cls");
    	cout<<"                         ~~Welcome to Black-O~~"<<endl;
    	cout << endl;
    		cout<<"Enter Name: ";
    		cin.get(person1.name,50,'\n');
    .
    .
    .

Popular pages Recent additions subscribe to a feed