1

I am trying to read a pasword and while I read it , display ** .

    cout << "\n Insert password : ";
loop1:
    string passw1 = "";
    char ch = _getch();
    while (ch != 13) // enter = char 13
    {
        if (!isalnum(ch))
        {
            cout << "\n\n Invalid character! Please insert the password again! ";
            goto loop1;
        }

        passw1.push_back(ch);
        cout << "*";
        ch = _getch();
    }

If I press for example , BACKSPACE , or SPACE or something that is not alpha-numerical , everything goes as planned. The problem is when I press any F key , or DELETE , HOME , INSERT , END , PG UP , PG DOWN , when the program crashes . Could you help me avoid the crash ? I would like to show an error message if an invalid key is pressed , not to have my program crash.

ildjarn
  • 62,044
  • 9
  • 127
  • 211
Teo
  • 3,394
  • 11
  • 43
  • 73
  • The problem is that `Del`, `Home` etc don't generate characters in the first place – they are control commands to move the cursor, just like the arrow keys. You're reading the input character by character, though, so you can't use them to edit the line which you are currently writing. That's why they don't work with your program. – Felix Dombek Dec 30 '11 at 17:33
  • And rethink that loop, the `goto` is neither needed nor a good idea here - you're looping back over an object initialization - not sure if that's even legal. – Mat Dec 30 '11 at 17:35
  • Could you provide additional information about your environment? I ran this code on Windows 7 with MSVC 10 and did not see any crashes. – DRH Dec 30 '11 at 17:36
  • ok , so what should I do to avoid the crash ? Win 7 x64 , VS 2010 – Teo Dec 30 '11 at 17:37
  • @Mat: It is legal to jump *out* of an object's scope, but still usually a bad idea. – Mike Seymour Dec 30 '11 at 17:41
  • Does the program crash instantly when you hit the key or does it crash later? Have you run it through the debugger? – ChrisWue Dec 30 '11 at 17:53
  • It crashes instantly ... it is because of `the isalnum()` function... – Teo Dec 30 '11 at 18:02
  • It crashes in the call to `isalnum`? Then it's something else you are doing that's the problem. Probably overwriting memory somewhere. – Some programmer dude Dec 30 '11 at 18:32
  • 1
    @JoachimPileborg: turns out it's a debug assert, not really a crash. `_getch()` is returning -32 for DEL, which is causing `isalnum` to assert in debug mode. EDIT: it's returning 224, which the OP is putting in a signed char. – JoeFish Dec 30 '11 at 18:38

3 Answers3

1

Let's see if I understand what you're trying to do (in pseudocode):

Prompt the user for a password
Wait for the user to press any key

While the key pressed is not the enter key
    If the entered key is an alphanumeric
        Add the character to the password string
        Print an asterisk on the screen
        Accept another character
    Else
        Alert the user that they entered a non-alphanumeric
        Clear out the string and have the user start over again
    End If
End While

If that's not what you're after, then modify to taste.

What I think is happening is that you're not capturing all of the possible characters when you test what key was pressed. If DEL is giving you trouble, then figure out how to catch it or handle it (remove an asterisk from the screen, and delete a character from the string).

Good luck!

John
  • 15,990
  • 10
  • 70
  • 110
  • Yeah , you understood what I want to do . Well , I don't know how to handle the `DEL` key .. I know it's ASCII code is 127 but , because of the `isalnum()` function , the program crashes ... – Teo Dec 30 '11 at 18:04
  • Maybe check out `cin` to see if it's more capable? – John Dec 30 '11 at 18:12
1

It crashes on my Win7 x64 VS2010 system as well. Turns out _gech() is returning 224 for the DEL key, which is -32 in a signed char. This is causing isalnum() to assert internally.

I changed the char to an int (which is what _getch() is returning and isalnum() takes for a parameter) and the overflow problem went away. unsigned char works as well.

int main( )
{
    cout << "\n Insert password : ";
loop1:
    string passw1 = "";
    int ch = _getch();
    while (ch != 13) // enter = char 13
    {
        if (!isalnum(ch))
        {
            cout << "\n\n Invalid character! Please insert the password again! ";
            goto loop1;
        }

        passw1.push_back(ch);
        cout << "*";
        ch = _getch();
    }
    return 0;
}

Yields (pressing DEL each time):

Insert password :

Invalid character! Please insert the password again! *

Invalid character! Please insert the password again! *
JoeFish
  • 3,009
  • 1
  • 18
  • 23
0

Use the is alphanumeric function - isalnum(char c ) to check if the parameter c is either a decimal digit or an uppercase or a lowercase letter.

And then filter out characters less than 32 or higher than 122 like this : if (c > 32 && c <122) { Get_Password(); }

This MS Windows specific code below is not portable. For Linux/*NIX/BSD see this : Hide password input on terminal

#include <iostream>
#include <string>
#include <conio.h>

int main()
{
    std::string password;
    char ch;
    const char ENTER = 13;

    std::cout << "enter the password:  ";

    while((ch = _getch()) != ENTER)
    {

        if (ch > 32 && ch<122)
        {
            if (isalnum(ch))
            {
                password += ch;
                std::cout << '*';

            }

        }
    }
    std::cout <<"\nYour password is : " << password<<"\n\n";
    return 0;
}
Community
  • 1
  • 1
Software_Designer
  • 8,490
  • 3
  • 24
  • 28