Jump to content

This is for a programming assignment in c/c++. The issue im having is that the keyboard buffer isnt being cleared. If anyone is testing the code you can just hit any keys until the password timeout shows up. This is where the issue becomes evident. Any keys entered during the sleep() are held in the keyboard buffer(i assume) and it gets entered on the next function call. I attempted to clear the buffer with fflush(stdin), but this doesnt do anything. Does anyone have a suggestions?
Here is the code:
 

#include <iostream>#include <cstring>#include <cstdio>#include <windows.h>#include <conio.h>using namespace std;#define pass_phrase "mama"#define invalid_tries 10bool get_pass();int main(){    bool user_verify;    do{        user_verify=get_pass();    }while(!user_verify);//runs until user enters the correct password}bool get_pass(){    static int invalid_count=0;//keeps count of invalid inputs    char *password=pass_phrase, input;    if(invalid_count>invalid_tries){//timeout occurs here if user goes above number of allowed tries        cout<<"\nPassword timeout: "<<invalid_count-invalid_tries<<" min";        Sleep(200*invalid_count);    }    fflush(stdin);//attempt at clearing keyboard buffer. It doesnt seem to work    cout<<"\nPassword: ";    for(int counter=0;counter<strlen(password);counter++){//checking user input against password one letter at a time        input=getche();        if(input!=*(password+counter)){//exits if user input doesnt equal password            cout<<"\nError, invalid password.";            invalid_count++;            return(false);        }    }    return(true);}
Edited by AndThenThereWas1
added code tags :)
Link to comment
https://linustechtips.com/topic/149725-clearing-the-keyboard-buffer-coding-issue/
Share on other sites

Link to post
Share on other sites

fflush() on input streams is undefined behavior. Even if it does work it isn't guaranteed to completely clear it.

 

Here's a common solution to the problem

voidflush( void ){    int c;    while( (c = getchar()) != '\n' && c != EOF );}

You could make it more general

voidflush( FILE* fp ){    int c;    while( (c = fgetc(fp)) != '\n' && c != EOF );}

main(i){for(;i<101;i++)printf("Fizz\n\0Fizzz\bBuzz\n\0%d\n"+(!(i%5)^!!(i%3)*3)*6,i);}

Link to post
Share on other sites

 

fflush() on input streams is undefined behavior. Even if it does work it isn't guaranteed to completely clear it.

 

Here's a common solution to the problem

voidflush( void ){    int c;    while( (c = getchar()) != '\n' && c != EOF );}

You could make it more general

voidflush( FILE* fp ){    int c;    while( (c = fgetc(fp)) != '\n' && c != EOF );}

This solution works however my problem is that it requires the user to press enter. Is there an alternative way to do this without needing the user to press enter?

Link to post
Share on other sites

If you're using std::cin, you can run this before every "std::cin >> whatever;"

//clearing cin bufferstd::cin.clear();std::cin.ignore(std::cin.rdbuf()->in_avail());

I had similar problem with leftover \n and some other random characters. This worked for me.

What's getche()?

Link to post
Share on other sites

If you're using std::cin, you can run this before every "std::cin >> whatever;"

//clearing cin bufferstd::cin.clear();std::cin.ignore(std::cin.rdbuf()->in_avail());

I had similar problem with leftover \n and some other random characters. This worked for me.

What's getche()?

I just tried this, but after it loops back around the characters are still in the buffer and continue to get input.

getche() is a way to grab the user input without having to wait for the user to press enter. The moment the char is typed getche() inputs the char and echos the char to the screen.

The problem im facing has to do with the password timeout. During the timeout if the user types any keys they will sit in the buffer until the next loop where the characters are automatically input with getche(). I need to clear that buffer before getche() can retrieve them so that the user can actually get a chance to enter a password. Otherwise, they will have to wait for every key they hit to get input which will get longer with every invalid input. 

Link to post
Share on other sites

I just tried this, but after it loops back around the characters are still in the buffer and continue to get input.

getche() is a way to grab the user input without having to wait for the user to press enter. The moment the char is typed getche() inputs the char and echos the char to the screen.

The problem im facing has to do with the password timeout. During the timeout if the user types any keys they will sit in the buffer until the next loop where the characters are automatically input with getche(). I need to clear that buffer before getche() can retrieve them so that the user can actually get a chance to enter a password. Otherwise, they will have to wait for every key they hit to get input which will get longer with every invalid input. 

Well, it didn't work because ure not using std::cin. I've never heard of the getch stuff before, but after a nice lecture here I wouldn't use it, I'd go with standard std::cin, and check for timeout after user enters the password and hits enter.

You can easily calculate time passed by calling GetTickCount() on windows to an int right before std::cin, and again before to a different int, and check for timeout by simple subtraction

http://msdn.microsoft.com/en-us/library/ms724408%28v=vs.85%29.aspx

or

http://www.cplusplus.com/reference/ctime/time/ to make it platform independent.

Link to post
Share on other sites

Well, it didn't work because ure not using std::cin. I've never heard of the getch stuff before, but after a nice lecture here I wouldn't use it, I'd go with standard std::cin, and check for timeout after user enters the password and hits enter.

You can easily calculate time passed by calling GetTickCount() on windows to an int right before std::cin, and again before to a different int, and check for timeout by simple subtraction

http://msdn.microsoft.com/en-us/library/ms724408%28v=vs.85%29.aspx

or

http://www.cplusplus.com/reference/ctime/time/ to make it platform independent.

Unfortunately I dont have a choice in using getche() as its in the directions. Directions: "First you will be asking the user to enter a password that is not case sensitive. The password is mama. You validate the input one letter at a time. As soon as an incorrect letter is entered,  display invalid password and reprompt for the password. Use the getche( ) function to accomplish this...".

Link to post
Share on other sites

Unfortunately I dont have a choice in using getche() as its in the directions. Directions: "First you will be asking the user to enter a password that is not case sensitive. The password is mama. You validate the input one letter at a time. As soon as an incorrect letter is entered,  display invalid password and reprompt for the password. Use the getche( ) function to accomplish this...".

Assignments, gotta love the most nonsensical specs sometimes.

Why not just print 'Press enter to retry' once timeout is finished ?

I can't figure out a different solution :D

Link to post
Share on other sites

Assignments, gotta love the most nonsensical specs sometimes.

Why not just print 'Press enter to retry' once timeout is finished ?

I can't figure out a different solution :D

I couldnt find a solution either so i removed the password timeout. The "Press enter to retry" is a good idea so next time ill have to do that. Thanks for your help.

Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×