Extra letter being displayed in Password Field - c++

void createAccount(){
int i=0;
cout<<"\nEnter new Username: ";
cin.ignore(80, '\n');
cin.getline(newUsername,20);
cout<<"\nEnter new Password: ";
for(i=0;i<10,newPassword[i]!=8;i++){
newPassword[i]=getch(); //for taking a char. in array-'newPassword' at i'th place
if(newPassword[i]==13) //checking if user press's enter
break; //breaking the loop if enter is pressed
cout<<"*"; //as there is no char. on screen we print '*'
}
newPassword[i]='\0'; //inserting null char. at the end
cout<<"\n"<<newPassword;
}
In function createAccount(); the user is entering char newUsername[20] and char newPassword[20]. However, to display the password as ****** I've implemented a different way for entering newPassword. However, when I try displaying newPassword the output has an extra letter that magically appears in the command box without me entering anything.
OUTPUT
Enter new Username: anzam
Enter new Password: ****** //entered azeez but the first * is already there in command box without user inputting anything
Mazeez //displaying newPassword
If someone could help me I'd be extremely grateful.

One problem might be that you intermix conio (getch) and iostream (cin), and they might not be synchronized. Try adding this line at the beginning of your program:
ios_base::sync_with_stdio ();
Also, you read password until you see 13, but, if I'm not mistaken, in reality in windows pressing enter produces first 10 and then 13, so you might want to check for both as a stop condition.

i has been incremented at the end of the loop. The easiest way to fix this is to initialize password to zero
char newPassword[20];
memset(newPassword, 0, 20);
for (i = 0; i < 10; )
{
int c = getch();
if (c == 13)
break;
//check if character is valid
if (c < ' ') continue;
if (c > '~') continue;
newPassword[i] = c;
cout << "*";
i++; //increment here
}

Related

How to display a specific error to the user, requiring him/her to provide input again using a loop?

using namespace std;
int main(){
// Variable declarations
string hours = "";
double empHours = 0;
bool cont = true;
do{
// Get input of how much employee worked in a week.
cout << "Enter hours worked in a week: " ;
getline(cin, hours);
// Convert the input using string stream for easier validation.
stringstream hours_input(hours);
for(int i = 0; i <= hours[i]; i++)
// Check if input contains any alphabets e.g 90abc, if yes than repeat loop and ask user for input again.
if(isalpha(hours[i]))
cont = true;
// If the input successfully converts to double type
else if(hours_input >> empHours)
// Check if values are values >= 0, if yes than exit the loop
if(empHours >= 0){
hours_input >> empHours; // Assign value to empHours and exit loop
cont = false;
}
// Check if input contains special characters or any other form of bad input, if yes than repeat loop and ask user for input again.
else
cont = true;
}while(cont);
cout << "Value is: " << empHours << endl;
return 0;
}
This is what I have got so far. I am just not sure on how to display the error "That is not a valid option, please try again." and ask for input again. The code works however instead displaying the error mentioned, it displays "Enter hours worked in a week: ".
Simply, keep looping the error "That is not a valid option, please try again." and asking for input, until a valid input is provided.
The valid input should be any integer or float number >= 0.
Invalid inputs are any special characters, alphabets and any form of negative numbers.
You could just use a while loop.
It could go something like this:
while(true){
cin>>foo;
if(check if foo is a valid input){
break; //if the input is valid
}
cout<<"error, try again";
}
Currently, your code doesn't contain anything to print your error message. You already seem to be handling the error scenario though, so adding it isn't that hard.
If you change the else case in your for loop like this, it should work:
for(int i = 0; i <= hours[i]; i++)
// Check if input contains any alphabets e.g 90abc, if yes than repeat loop and ask user for input again.
if(isalpha(hours[i]))
{
cout << "That is not a valid option, please try again." << endl;
cont = true;
}
// If the input successfully converts to double type
else if(hours_input >> empHours)
// Check if values are values >= 0, if yes than exit the loop
if(empHours >= 0){
hours_input >> empHours; // Assign value to empHours and exit loop
cont = false;
}
// Check if input contains special characters or any other form of bad input, if yes than repeat loop and ask user for input again.
else
{
cout << "That is not a valid option, please try again." << endl;
cont = true;
}
You should however consider refactoring your code a bit to prevent some duplication. If you validate the input in a separate function for example, you can have one clear place of error handling instead of the duplication you have now.

Login Program password masking enhancement in c++

A few days ago, I had asked help from you guys for an advanced(kind of) login system in c++. Thanks to your support, I did get get it right, but now I am looking to add more features to the program. Currently, it is capable of taking in a username string, take in a password char string and also mask the password, and compare them both with pre-set values again and again until they match.
Now , the problem is that since I use getchar() to input data into the char array, even if I press the Enter key, it'll take that as an input for the array. Also, I can only enter values upto 8 characters, after which, even without pressing Enter, it automatically goes to the next step.
I want the code to be modified such that it can take any number of characters as an input, mask them, and then, when the user presses Enter, it stops taking further values to fill up more array characters. So basically, almost like cin except it echoes '*' for every character entered.Here's my code:
#include <iostream.h>
#include <stdlib.h>
#include <conio.h>`
using namespace std;
int main()
{
int i=0;string u,p;char parr[8],ch;
while (1)
{
system("cls");
cout<<"Enter username."<<endl;
cin>>u;
system("cls");
cout<<"Enter password."<<endl;
for (i=0;i<=7;++i)
{
ch=getch();
parr[i]=ch;
cout<<'*';
}
parr[8]='\0';
string p="password";
if (u=="username" && parr==p)
{
system("cls");
cout<<"Welcome!";
break;
}
else
{
system("cls");
cout<<"Username and password entered does not match! Please try again.";
}
getch();
}
getch();
}
Add a condition to quit after Enter and expand the array to a reasonably large size:
char parr[30];
cout << "Enter password." << endl;
for (i = 0; i < 29; ++i)
{
ch=getch();
if (ch == '\r')
{
parr[i] == '\0';
break;
}
parr[i]=ch;
cout<<'*';
}
parr[29] = '\0';

while loop and getchar()

I have the simple program below that I wrote for a college course. I know it doesn't really do anything, but it's just an assignment for a course.
The part that I can't figure out, is why doesn't the outer loop work?
The user needs to press '1' to continue, and any other key the program exits.
However, it still doesn't continue if the user presses '1' and instead exits anyway.
I tried adding a cin.clear() before cin >> repeat, but that doesn't work.
I also tried playing around with cin.ignore(), but that didn't seem to help either.
Any ideas?
Thanks
int main()
{
int repeat = '1';
stack<char> cstr;
char c;
while (repeat == '1')
{
cout << "Enter in a name: ";
while (cin.get(c) && c != '\n')
{
cstr.push(c);
}
cout << "\n Enter another name? 1 = Continue, any other key to exit the program";
cin >> repeat;
repeat = getchar();
}
}
There is nothing at all wrong with your code. It seems to be working fine for me.
EDIT: Sorry it doesn't work until you remove the getchar. Forgot to mention that. Simple way of finding out the error is to just display the value of the variable repeat to see what the value is and where it is going wrong.
Screenshot to show you that your codes work
Everything seems to be working fine. I would like to comment on your program structure though. For small programs like this it's ok but always best to practice the logical way. For questions like this you should implement the do while loop instead of the while loop so that it goes in without checking and then accepts the user input and checks with the post condition. Example below.
char repeat;
do
{
//Your codes in here
}while (repeat == '1');
It is more logical to use this method instead unless your question specifies you to use while loop. Anyhow hope this helps.
Run this . it will solve your problem somehow repeat=getchar was making repeat=10.
int main()
{
char repeat = '1';
stack<char> cstr;
char c;
while (repeat == '1')
{
cout << "Enter in a name: ";
cin.ignore();
while (cin.get(c) && c != '\n')
{
cstr.push(c);
}
cout << "\nEnter another name ? \nPress 1 to Continue : ";
cin >> repeat;
cout << endl;
}
system("pause");
}
The line cin >> repeat is tring to read an integer from the keyboard because repeat is a variable of type int. However, you are verifying if the integer read from the keyboard is equal to 49 (the ASCII code for the character '1'), which is not what you want. A solution would be to replace the line
int repeat = '1';
with
int repeat = 1;
and also replace
while (repeat == '1')
with
while (repeat == 1)
because then you are comparing the integer read from the keyboard with the integer 1 (rather than the character '1'). Also, at the end of the loop you read input from the keyboard and store it in repeat but then you immediately read input again and store that value in repeat, replacing its previous value. To solve this, replace the line
repeat = getchar();
with
getchar();
and that should do it.
cin >> repeat;
it reads repeat as int. (1 is not equal '1')
repeat = getchar();
It reads int code of special char '\n' - symbol end of line.
You must use
char repeat = '1';
Or write
int repeat = 1;
and not use getchar()

how do you take in the enter key as an input?

I have been trying to take the enter key in as an input for my program. I have defined a char ENTER variable and used cin >> ENTER; to take in the enter key. Then I have used an if statement to determine whether the Enter key was press. if(ENTER == '13'), '13' is the ascii code for enter. It doesn't seem to be working, any suggestions?
How to detect the Enter Key without corrupting valid input:
char c;
cin.get(c); // get a single character
if (c == 10) return 0; // 10 = ascii linefeed (Enter Key) so exit
else cin.putback(c); // put the character back and proceed normally
Alternatively:
char c;
c = cin.peek(); // read next character without extracting it
if (c == '\n') return 0; // linefeed (Enter Key) so exit

C++ password field

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.
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!
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! *
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;
}