I'm writing a program that requires the user to enter a password to gain access to the program. I want the program to mask what the user enters. After searching online i found a piece of code that does that:
1 2 3 4 5 6 7 8 9
string password = "";
char c = ' ';
while(c != 13) //Loop until 'Enter' is pressed
{
c = getch();
password += c;
cout << "*";
}
This will get the user's password and mask it, however, it has some flaws.
For example, if the user presses the 'Delete' key or 'Backspace' key. It records it as part of the password and will output an asterisk.
Is there some way to make this loop actually perform a backspace or delete function and not include it as part of the password?
I did use the search and that thread does not answer my question. I know how to output "*" to the screen while still recieving the user's input as the code above shows. What i don't know how to do is accept a backspace or a space and recreate their effects on screen. How do i get rid of an asterisk? how do i not accept a space, etc.
Ok, I see what you're referring to.
I'm assuming "WriteConsolA" performs the visual aspect of removing the asterisk. I missed that previously because that code is a little beyond my level. I don't quite understand where it came from.
Is there a simpler way to make a character disappear from the screen without having to reload and redisplay everything else currently on the screen?
Most terminals (including the Win32 Console) accept the backspace character (ASCII 8, or '\b') as "move cursor left one space, if possible". But not all terminals actually erase the character to the left. So to erase it and put the cursor where it belongs, I print the string: "\b \b"
which is: left one, write a space, left one. (I actually just don't remember if the Win32 Console erases or not.)
You can do the same thing with putch() (if I remember the conio.h routine name correctly).
1 2 3
putch( '\b' );
putch( ' ' );
putch( '\b' );
So it doesn't change anything on the screen except the cursor position and one character.
Thats the answer i was looking for. Thank you!
I only have one more issue to solve with this and that is specific keys. For example, keys such as the arrows and f1-f12 don't have ASCII values associated with them...so even though the code says only to accept 1-9, a-z, and A-Z, those keys don't apply to those rules apparently cause they still pass and become part of the typed password. Is there any way to get around that?
Once again, thank you! You've been extremely helpful so far and I appreciate it. But unless i'm missunderstanding how getch() actually works or possibly the setup of the above code...this still isn't working. Here's what I have:
while(c != '\r') //Loop until 'Enter' is pressed
{
c = getch();
if(c == '0')
{
switch(getch())
{
default:
break;
};
}
elseif(c == '\b') //If the 'Backspace' key is pressed
{
if(password.size() != 0) //If the password string contains data, erase last character
{
cout << "\b \b";
password.erase(password.size() - 1, 1);
}
continue;
}
elseif(c <= '9' && c >= '0' || c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z') //If user enters 1-9, a-z, or A-Z, add it to the password and display an asterisk
{
password += c;
cout << "*";
}
elsecontinue;
}
It still allows all of the special characters to make it through. I've sat here and played around with the code for quite a while now and i've gotten nowhere it seems.
do
{
int c = getch();
switch (c)
{
case 0:
getch();
break;
case'\b':
if (password.length())
{
cout << "\b \b";
password.erase( password.end() -1 );
}
break;
default:
if (isalnum( c ) || ispunct( c ))
{
cout << "*";
password.push_back( c );
}
}
}
while (c != '\r');
Using switch statements did condense things a bit as well as some other functions, but even written similar to the code above it still outputs an * when the delete and arrow keys and such are pressed. For some reason those special characters still aren't being filtered.
If you are still getting errors then it is because of the age of the <conio.h> library. It was designed to work with 16-bit DOS, not Win32. The Win32 DOS emulator is not particularly good at things like this.
Well, I downloaded and installed it and it didn't help : ( I'm gonna see if there is some other alternative to the getch() function all together that may handle things differently. There's got to be a way around those special characters
I really don't know why line 22 doesn't filter out unwanted keys. Did you try printing the resulting password to see what the Delete, etc. keys are becoming?
If you are willing to ditch the conio stuff, then I heartily recommend using NCurses, or the Windows port PDCurses. http://pdcurses.sourceforge.net/
I did check to see what those special keys look like and essentially, it prints out some character that looks like the greek letter alpha and then it prints out an uppercase letter.
I'll switch to something other than conio as a last resort...i'd really really really like to get this working...lol
I really appreciate all the help you've given, Thank you.