password masking

closed account (1vf9z8AR)
Where am i wrong?

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
  #include<iostream>
#include<conio.h>
using namespace std;
int main()
{
        string pass;
        char ch;
        int pos=0;
        cout<<"Enter password";
        for(int i=0;i<100;i++)
        {
                ch=getch();
                if(ch==13)
                        break;
                else if(ch==8)
                        {
                                cout<<"\b";
                            pass[--pos];
                        }
                else
                {
                        cout<<"*";
                        pass[pos++]+=ch;
                }
        }
}
On line 23, you have to do pass [pos++] = ch instead of what you did
Forget about pos. You don't need it. But you do need pop_back()
http://www.cplusplus.com/reference/string/string/pop_back/

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
#include <iostream>
#include <string>
#include <conio.h>

using namespace std;

int main()
{
    string pass;

    cout << "Enter password";
  
    for (int i=0; i<100; i++)
    {
        char ch = getch();
  
        if (ch == 13)
            break;
            
        if (ch == 8)
        {
            if (pass.size())
            {
                cout << "\b \b";
                pass.pop_back();
            }
        }
        else
        {
            cout << "*";
            pass += ch;
        }
    }
        
    cout <<  "pass = " << pass << '\n';
}


or the same idea, with the for-loop handling some of the task:
1
2
3
4
5
6
7
8
9
10
11
12
13
    for ( char ch; ch = getch(), ch != 13; )
    {
        if (ch == 8 && pass.size())
        {
            cout << "\b \b";
            pass.pop_back();
        }
        else
        {
            cout << "*";
            pass += ch;
        }
    }

Note the comma operator here: ch = getch(), ch != 13 only the part after the comma is evaluated as the loop condition.
Last edited on
One more thing, to answer the original question, "Where am i wrong?", the original code was attempting out of bounds access to the string. You can show this by replacing pass[] with pass.at(). They both do effectively the same thing, but the at() member function does range checking and generates an exception if the subscript is out of range.
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
#include<iostream>
#include<conio.h>
#include <string>
using namespace std;
int main()
{
    string pass;
    char ch;
    int pos=0;
    cout<<"Enter password";
    for(int i=0;i<100;i++)
    {
        ch=getch();
        if(ch==13)
            break;
        else if(ch==8)
        {
            cout<<"\b";
            pass.at(--pos);
        }
        else
        {
            cout<<"*";
            pass.at(pos++)+=ch;
        }
    }
    
    cout << "\npass = " << pass << " length = " << pass.size() << '\n'; 
}

If you run this and simply press enter, you will see an output like this:
Enter password
pass =  length = 0


Run it again and press any other key, you may see something like this - depending on compiler.
Enter password*terminate called after throwing an instance of 'std::out_of_range'
  what():  basic_string::at

This application has requested the Runtime to terminate it in an unusual way.
Please contact the application's support team for more information.

closed account (1vf9z8AR)
@Chervil

I am trying your codes in post number 2 with the pop back function but

it shows enter password but i can't input anything.

i am using codeblocks and windows.
I just tested it on code::blocks 16.01, windows 8.1

I typed "asdfg" then pressed backspace two times, then enter.

Enter password***pass = asd

Process returned 0 (0x0)   execution time : 11.563 s
Press any key to continue.


Note that the pop_back() function for string requires compiler option -std=c++11 (or later). The default I think in code::blocks is still c++98 mode.

An alternative would be something like pass.erase( pass.size() - 1 ); or maybe pass.resize( pass.size() - 1 );

But I don't recommend those. Just make sure you have set the compiler option for c++11.
closed account (1vf9z8AR)
yes i am using c++11.
syashsing234, are you running
http://www.cplusplus.com/forum/beginner/224831/#msg1028137
or are you running
http://www.cplusplus.com/forum/beginner/224831/#msg1028200 ?

(msg1028200)'s code is supposed to fail and cause a runtime exception. Chervil's first post (msg1028137) is what works on my machine (MinGW g++ 7.1.0, Windows 10), and should work on your machine (if Windows and MinGW), too.

Edit: I see you said you are using the pop_back code.
Are you sure you're running the code verbatim?
Are you getting any compiler warnings?
What name+version is the compiler you downloaded with Code::Blocks?
Is the program crashing, or does it just hang at getch()?

An alternative to the ancient getch would probably have to come from a library that hides part of the console, such as ncurses. But I am not familiar with, so sorry if this post is useless.
Last edited on
Topic archived. No new replies allowed.