For the newbies: new input algorithm

I have created a new input algorithm for my "passwords and accounts" program that i thought was worth sharing. It uses 2 variables: a character and a string to get string input from the user 1 character at a time. This allows for additional options such as 'press escape to quit'. I used it to hide the characters, allow the user to cancel input, and enter the input. You can modify it to fit your needs (whatever they are). Here is the source code of the algorithm:

include files:

<iostream>
<string>
<conio.h>
<windows.h>

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
string opt_input(string prompt = ">")
{
    char ch;        /**string prompt: when this function is called with no argument, the default is ">" */
    int x = 0;
    string input;
    input.clear();  //clearing the string just to be safe (memory concerns)
    while(x == 0)
    {
        cls();  //system("CLS");
        cout<< prompt<< input<< endl;
        cl();         // Sleep(100);While(_kbhit()) _getch();
        ch = _getch();
        if(ch == 0x0d)
        {
            return input;
        }
        else if((ch == 0x08) && (input.size() > 0))
        {
            input.resize((input.size() - 1));
        }
        else
        {
            input = (input + ch);
        }
    }
    return input;
}


so, i can call this function like this:

1
2
3
4
5
6
7
8
9
10
int input_test()
{
    cls();
    string ret;
    ret = opt_input("Enter somthing: ");   /**any_string = opt_input(string message) */
    cls();
    cout<< "Returns: "<< ret<< endl;  //what to do with the string?  display it
    pause();
    return 0;
}


here is 'pause()' :

1
2
3
4
5
6
7
8
9
void pause()
{
    cl();
    while(!_kbhit())
    {
        continue;
    }
    cl();
}


put it together and try it out. Its pretty cool actually. Good luck programming! xD
Last edited on
Now, keep in mind, for those of you who are extrememely new, that when you use this algorithm an if, else if, and else statement has to be used to specify what buttons do what. If we call this algorithm without having 'if(ch == 0x0d)', you will never be able to break th loop, and the function will, as a result, never return. Commands you will want to add to this algorithm every time: backspace and enter. The user needs to be able to backspace his/her input, and of course we also need to be able to enter it in the first place. Optionally, you can add other commands, such as escape to cancel, or delete to clear the input all-together (string.clear()). Have fun.
When someone presses backspace before entering any characters, it gets saved to input. Does that affect password entry in any way?
That is the point. Here are the steps of the algorithm:

loopforever:
1. display message and input (input is nothing when it starts)
2. wait until the user presses a key
3. identify key, and if it is backspace, resize the string to string.size() - 1; if its enter, return input
4. else, it isnt a command. We append the character pressed to the end of the string like so: string = (string + character)
5. repeat steps 1-5

basically, it appends every character except those specified by the 'if' statements you place. If the character pressed is a comand, it will execute it, otherwise, it will append the character to the end of a string (in this instance 'input').

What i did for my password program was eliminate the part where it actually displays input, and replaced it with a for loop which (in place of the string) displays * character for each character of the string. The result is that the input is "hidden". This is just for display, and doesn't actually modify the 'input' string. It just displays a * character for each character of the string, so that there are the same amount of * characters as there are characters in the 'input' string. You should compile and run this little program before asking further questions.
Easy to understand and highly usable way.Backspace,ESC and Enter works(if included in code).I use this code

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
void Menu::prog_pass()
{
	clrscr();
	char pass[15]="\0",temp;
	gotoxy(22,12) ;
	cout <<"Enter program pass password : " ;
	for(int z=0;z<15;z++)
	{
		temp=getch();
		clreol;
		if(temp==(char)13)
		 break;
		if(temp==(char)8)
		{
		  z--;
		  temp=NULL;
		  pass[z]=temp;
		  cout<<"\b";
		  clreol();
		  z--;
		  continue;
		}
		cout<<"*";
		pass[z]=temp;
	}
	if(!strcmp(pass,"password"))
	{
	  return ;
	}
	clrscr();
	gotoxy(25,12) ;
	cout <<"   WRONG PASSWORD!!!!     " ;
	getch() ;
	exit(0);
}
@IWishIKnew

What I meant was that I think you should change this part of your code:

1
2
3
4
else if((ch == 0x08) && (input.size() > 0))
{
	input.resize((input.size() - 1));
}

to this:

1
2
3
4
5
else if (ch == 0x08)
{
	if (input.size() > 0)
		input.resize((input.size() - 1));
}

As it is right now, if someone presses the backspace key before inputting any other letters, it gets saved to your input variable.

I used this main function to test it:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
int main(void)
{
    system("CLS");
    string ret;
    ret = opt_input("Enter something: ");   /**any_string = opt_input(string message) */
    system("CLS");
    cout << "Returns: " << ret << endl;  //what to do with the string?  display it
    cout << "Size is " << ret.size() << " characters.\n";
    string str;
    cout << "Re-enter what you typed: ";
    cin >> str;
    if (str == ret)
        cout << "It matches the stored word.\n";
    else
        cout << "It doesn't match the stored word.\n";
    system("PAUSE");
    return 0;
}

If I type "password", the output is correct:

Returns: password
Size is 8 characters.

But if I press backspace before typing "password" then the output is like this:

Returns:password
Size is 9 characters.

Then if I try to type in "password" when prompted to re-type what I had, the result is:

Returns:password
Size is 9 characters.
Re-enter what you typed: password
It doesn't match the stored word.

While I suppose this really isn't a big deal, and it's unlikely that someone would press backspace before typing anything, it's such an easy fix I wanted to point it out.

EDIT:

Actually, now that I think about it, it is a big deal. How many of us have started typing a password, then had a typo, and deleted what we typed? And even though we only typed 5 letters or so, we press backspace 7-8 times?
Last edited on
we can stop backspace work if password is character array as in my code.So pressing backspace many times doesn't do anything.
...
1
2
3
4
else if((ch == 0x08) && (input.size() > 0))
{
	input.resize((input.size() - 1));
}


and

1
2
3
4
5
else if (ch == 0x08)
{
	if (input.size() > 0)
		input.resize((input.size() - 1));
}


are exactly the same thing. EXACTLY THE SAME. if backspace is pressed, then input.size() > 0 for anything to be accomplished. Adding it into and AND statement just decreases the number of lines of code written.

So, yes i did find that small bug when i was testing my passwords program. I had fixed it too. Here is the modification made:

1
2
3
4
5
6
7
else
        {
            if(ch != 0x08)
            {
                input = (input + ch);
            }
        }


in other words: If the character being added to the string is not 'backspace', then add the character to the string. There are no other bugs.

EDIT: btw, yes it is a problem. when you backspace (just hold it down until there aren't any characters), somtimes you hold it down just long enough for it to register 1 last character. Thats actually how i found it.

EDIT2: And btw, i dont use an array, or vector because i NEED it to work with strings, as i plan to use this algorithm for other things, like encryption, menus, or even command line programs. This is a very useful algorithm when it comes to commands, and strings. I can use it to bring together both keyboard commands, strings, and special string recognition commands (like mabey "#dothis" = select_menu_item(int menu_item_number) or somthing). I have found that i require this function alot when im writing a program.
Last edited on
Actually, the two aren't exactly the same if you consider your whole if-else-if block.

Your original:

1
2
3
4
5
6
7
8
9
10
11
12
if(ch == 0x0d)
{
	return input;
}
else if((ch == 0x08) && (input.size() > 0))
{
	input.resize((input.size() - 1));
}
else
{
	input = (input + ch);
}

So if someone pressed backspace, but input size is 0 then the conditions else if((ch == 0x08) && (input.size() > 0)) will fail, and we head to the else

1
2
3
4
else
{
	input = (input + ch);
}

And that would add the backspace character to the input string.


Modified:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
if(ch == 0x0d)
{
	return input;
}
else if(ch == 0x08)
{
	if (input.size() > 0)
	{
		input.resize((input.size() - 1));
	}
}
else
{
	input = (input + ch);
}

In this, if someone presses the backspace button, then no matter what the size of the input string at the moment, the backspace character will never be added to the input string.
Except that you've got
1
2
3
4
5
6
7
8
else if((ch == 0x08) && (input.size() > 0)){
//...
}
else{
//this would execute if input is empty
//without caring for what key you pressed
//...
}
Compare to
1
2
3
4
5
6
7
8
9
else if (ch == 0x08)
{
	if (input.size() > 0)
		input.resize((input.size() - 1));
}
else{
//This would execute when you didn't press 0x08
//...
}
Isn't there a freaking KEY_BACKSPACE constant/macro defined somewhere.


By the way ¿what does cl mean?
@ fg100 OH! I get you. intresting.

@ne555
I wrote cl() as function. It clears the _getch() stream. Its a lot easier to just write 'cl() instead of the whole thing. Here is cl():

1
2
3
4
5
void cl()
{
    Sleep(10);
    while(_kbhit()) _getch();
}


Also, there isnt a "freaking KEY_BACKSPACE" macro. look up 'Virtual Key Codes', and use the number/letter codes (not the IDs, IDs are used with GetAsyncKeyState(VK_BACK/any other key)) I saved the source code of the site with all the key codes so i always have them. I can also look them up easier (ctrl + f = search for text in browser). I hope this helped.
Topic archived. No new replies allowed.