Trying to do a password validation method in order to allow a user to use my program.
I was wondering how would someone would implement such a code that allows the program to compare two strings, going down all the letters and numbers to make sure everything matches, and then allows a user to access program controls after successfully entering in a password.
So, for example, if the password is "h3llo" and someone typed in "he" the program will output an error message saying that the password is incorrect.
Here is what I started with:
void checkPassword() {
cout << "Enter password: ";
string password = "H3110W0r1d";
int length = password.length();
int i;
string input;
cin >> input;
for (i = 0; i < length; i ++) {
if ((input[i].compare(length[i]))) == 1) {
if ((input[i].compare(length[i])) == 0) {
cout << "Error! Wrong password!";
} else {
cout << "Welcome!";
}
}
I've tried so many different ways, however, I can't seem to get it working. Any help on what I am doing wrong?
Simply just compare one by one.
void checkPassword() {
cout << "Enter password: ";
string password = "H3110W0r1d";
int length = password.length();
int i;
string input;
bool ok = true;
cin >> input;
if (input.length() != password.length()) {
ok = false;
} else {
for (i = 0; i < length; i ++) {
if (input[i] != password[i]) {
ok = false;
break;
}
}
}
if (ok) {
cout << "Welcome!";
} else {
cout << "Error! Wrong password!";
}
}
Or more simply
void checkPassword() {
cout << "Enter password: ";
string password = "H3110W0r1d";
string input;
cin >> input;
if (input == password) {
cout << "Welcome!";
} else {
cout << "Error! Wrong password!";
}
}
Related
I'm trying to limit user input to certain characters only [a-z,A-Z,SPACE,PERIOD], I can't get this function right?!
void setName()
{
char fname[20];
unsigned int ascii_val;
while(ascii_val<65 || ascii_val>90)
{
cout << "First Name: ";
cin.ignore().getline(fname,20);
for(int i=0; i<sizeof(fname); i++)
{
ascii_val = toupper(fname[i]);
if(ascii_val==32 || ascii_val==46 || ascii_val==0) //Exception to allow SPACE and PERIOD
{
ascii_val=65;
};
if(ascii_val<65 || ascii_val>90)
{
cout << "Only Alphabet [a-z,A-Z,SPACE,DOT] Allowed!\n";
break;
}
}
}
newfname = fname;
}
This finally worked! if you think this is not the best solution, post your alternative please.
bool charVerify(string word)
{
for (int i = 0; i < word.size(); i++)
{
int character = toupper(word[i]);
if(character == ' ' || character == '.')
{
character='A';
}
if (character < 'A' || character > 'Z')
{
return false;
}
}
return true;
}
void setFname()
{
string fname;
cout << "Enter Name: ";
getline(std::cin.ignore(),fname);
while(1)
{
if (charVerify(fname))
{
break;
}
else
{
cout << "\tInvalid Input! Only [a-z,A-Z,SPACE,PERIOD]" << endl;
}
cin.clear();
cout << "Enter Name: ";
getline(std::cin.ignore(),fname);
}
firstname = fname;
}
I'm creating a program that is password protected. I have a function with a validation loop called getPassword() that allows the user to type in password attempts as many times as they want, but now I want to limit them to only 3 attempts. Would I be able to do this in the getPassword() function or do I have to create another function?
I've tried making the getPassword() into a do while loop and used a for-loop to inside the do while to count how many times the user attempts entering the password and tried to get it to break when the counter reached 3, but that doesn't seem to get me out of the do while loop. Any suggestions?
void getPassword()
{
int i = 0;
string password = "sup";
string userInput;
int wrongPasswords = 0;
for (int i = 0; i < 3; i++)
{
cout << "Please enter your password: " << endl;
cin >> userInput;
cin.ignore(1000, 10);
while (true)
{
if (userInput != password)
{
cout << "Invalid. Please try again. You can only attempt
password 3 times." << endl;
wrongPasswords++;
break;
}//if
if (wrongPasswords == 3)
break;
}//while
}//for
}//getPassword
Edited code:
void getPassword()
{
string password = "sup";
string userInput;
for (int i = 0; i < 3; i++)
{
cout << "Please enter your password: " << endl;
cin >> userInput;
cin.ignore(1000, 10);
if (userInput == password && i < 3)
break;
}
}//getPassword
You can also try with bool instead of void function. Return true if password was correct, exit program after failing three times. For example,
bool getPassword() {
for ( int attempts = 0; attempts < 3; ++attempts ) {
std::string password;
std::cout << "Enter your password: " << password << std::endl;
std::getline(std::cin, password);
if ( password == "1" ) {
std::cout << "Welcome!";
return true;
}
}
return false;
}
In your main function, call getPassword() function,
int main() {
if ( !getPassword() )
return true;
std::cout << std::endl;
}
This seems more elegant and would have used bool instead of void, unless you have reason not to.
Yet another snippet:
bool tryLogin() {
string pwd = "hello";
string inp;
int tries = 1;
while (true) {
cout << "\nEnter password ";
cin >> inp;
if (inp.compare(pwd) == 0) return true;
++tries;
if (tries > 3) {
cout << "\n Max number of trials exceeded\n";
break;
}
}
return false;
}
int main()
{
cout << endl << (tryLogin() ? "Login successful" : "Can't login") << endl;
}
I've made an app that solves some computations with matrices, and I want to authenticate users in order to grant them access when the program starts.
I will show you what I've done already.
int main()
{
const string USERNAME = "claudiu";
const string PASSWORD = "123456";
string usr, pass;
cout << "Enter Username : ";
cin >> usr;
if(usr.length() < 4)
{
cout << "Username length must be atleast 4 characters long.";
}
else
{
cout << "Enter Password : ";
cin >> pass;
if(pass.length() < 6)
{
cout << "Password length must be atleast 6 characters long";
}
else
{
if(usr == USERNAME && pass == PASSWORD)
{
cout << "\n\nSuccessfully granted access" << endl;
}
else
{
cout << "Invalid login details" << endl;
}
}
}
This is how my code looks like. All I want to do is that when I enter a wrong username or a wrong password the program shows the message I wrote and then let me introduce another username and password and when I introduce them correctly, the program starts.
I would make a logged_in variable, then set it to true when the condition is passed and run the whole login process in a while loop:
#include <iostream>
#include <string>
using namespace std;
int main()
{
const string USERNAME = "claudiu";
const string PASSWORD = "123456";
string usr, pass;
bool logged_in = false;
while (!logged_in)
{
cout << "Enter Username : ";
cin >> usr;
if (usr.length() < 4)
{
cout << "Username length must be atleast 4 characters long.";
}
else
{
cout << "Enter Password : ";
cin >> pass;
if (pass.length() < 6)
{
cout << "Password length must be atleast 6 characters long";
}
else
{
if (usr == USERNAME && pass == PASSWORD)
{
cout << "\n\nSuccessfully granted access" << endl;
logged_in = true;
}
else
{
cout << "Invalid login details" << endl;
}
}
}
}
cout << "Passed login!\n";
}
I have the following code:
qstn:
cout << "Input customer's lastname: ";
getline(cin, lname);
if (lname.find_first_not_of("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ ") != string::npos) {
cout << "You can only input alpha here!\n";
cin.clear();
goto qstn;
} else if (lname.empty()) {
cout << "Please enter your firstname!\n";
cin.clear();
goto qstn;
}
int lnamel = lname.length();
int strl = str.length();
int is = 0;
for (int i = 1; i < strl;) {
i++;
is++;
if (lname[i] == lname[is] && lname[i] == ' ' || lname[0] == ' ') {
cin.clear();
cout << "Please input your lastname properly!\n";
goto qstn;
}
}
// next question here
I'm having a hard time on thinking what will be the proper logic to avoid the
goto statement, since I was college I was using it but someone here said that
it's not good to use it at all cause it might ruin my code.
I tried using the do while loop but it's not smooth as goto.
Please help!
Here's an idiom I like to use:
int i;
if (std::cin >> prompt("enter an integer: ", i))
{
std::cout << "Read user input: " << i << "\n";
} else {
std::cout << "Input failed (too many attempts). Eof? " << std::boolalpha << std::cin.eof() << "\n";
}
Here, prompt is a smart input manipulator, that takes care of handling parse errors or stream failures and retrying.
It's quite generic so actually do many things, but you don't need to indicate all the options. When the manipulator is inserted into the stream it relays to the do_manip member:
template <typename Char, typename CharT>
friend std::basic_istream<Char, CharT>& operator>>(std::basic_istream<Char, CharT>& is, checked_input<T, Prompter>& manip) {
return manip.do_manip(is);
}
The do_manip handles all the logic without any gotos :) :
std::istream& do_manip(std::istream& is) {
auto attempt = [this] { return infinite() || retries_ > 0; };
while (attempt()) {
if (!infinite())
retries_ -= 1;
prompter_(out_);
if (is >> value_) {
if (!run_validators(out_))
is.setstate(is.rdstate() | std::ios::failbit);
else
break;
} else {
out_.get() << format_error_ << "\n";
}
if (attempt()) {
is.clear();
if (flush_on_error_)
is.ignore(1024, '\n');
}
}
return is;
}
You can see that there is a possibility to have validations run before accepting the input.
Here's a somewhat full-blown demo:
Live On Coliru
int main() {
using namespace inputmagic;
int i;
if (std::cin >> prompt("enter an integer: ", i)
.retries(3)
.flush_on_error(false)
.format_error("I couldn't read that (Numbers look like 123)")
.output(std::cerr)
.validate([](int v) { return v > 3 && v < 88; }, "value not in range (3,88)")
.validate([](int v) { return 0 == v % 2; })
.validate([](int v) { return v != 42; }, "The Answer Is Forbidden")
.multiple_diagnostics())
{
std::cout << "Read user input: " << i << "\n";
} else {
std::cout << "Input failed (too many attempts). Eof? " << std::boolalpha << std::cin.eof() << "\n";
}
}
You can see it will only accept valid integers
that are >3 and <88,
that are even
except 42 (forbidden number)
When entering the numbers 21, 42 and 10 on subsequent retries, you get: live
enter an integer: 21
Value not valid
enter an integer: 42
The Answer Is Forbidden
enter an integer: 10
Read user input: 10
However, if you enter 1 all the time you get this: live
enter an integer: 1
value not in range (3,88)
Value not valid
enter an integer: 1
value not in range (3,88)
Value not valid
enter an integer: 1
value not in range (3,88)
Value not valid
Input failed (too many attempts). Eof? false
Or if you read from a single line file: live
enter an integer: value not in range (3,88)
Value not valid
enter an integer: I couldn't read that (Numbers look like 123)
enter an integer: I couldn't read that (Numbers look like 123)
Input failed (too many attempts). Eof? true
Use a function:
bool getLastName(string & lname,
string & str)
{
cout << "Input customer's lastname: ";
getline(cin, lname);
if (lname.find_first_not_of("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ ")
!= string::npos)
{
cout << "You can only input alpha here!\n";
cin.clear();
return false;
}
else if (lname.empty())
{
cout << "Please enter your firstname!\n";
cin.clear();
return false;
}
int lnamel = lname.length();
int strl = str.length();
int is = 0;
for (int i = 1; i < strl;)
{
i++;
is++;
if (lname[i] == lname[is] && lname[i] == ' ' || lname[0] == ' ')
{
cin.clear();
cout << "Please input your lastname properly!\n";
return false;
}
}
return true;
}
All I've done here is replace the gotos with return false. If the program makes it to the end of the function, return true. Make the function call in a while loop:
while (!getLastName(lname, str))
{
// do nothing
}
Not only does this de-spaghettify the code, but it breaks it up into nice, small, easy to manage pieces. This is called procedural programming.
A While loop looks like your best bet. You can redo the loop with the continue keyword.
int incorrect = 0;
while(!incorrect) {
cout<<"Input customer's lastname: ";
getline(cin,lname);
if(lname.find_first_not_of("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ ")!=string::npos)
{
cout<<"You can only input alpha here!\n";
cin.clear();
continue;
}
else if(lname.empty())
{
cout<<"Please enter your firstname!\n";
cin.clear();
continue;
}
int lnamel=lname.length();
int strl=str.length();
int is=0;
for(int i=1; i<strl;)
{
i++;
is++;
if(lname[i]==lname[is]&&lname[i]==' '||lname[0]==' ')
{
cin.clear();
cout<<"Please input your lastname properly!\n";
continue;
}
incorrect = 1;
}
You need to use some do while loops
for instance this:
qstn:
cout<<"Input customer's lastname: ";
getline(cin,lname);
if(lname.find_first_not_of("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ ")!=string::npos)
{
cout<<"You can only input alpha here!\n";
cin.clear();
goto qstn;
}
else if(lname.empty())
{
cout<<"Please enter your firstname!\n";
cin.clear();
goto qstn;
}
could be re-written as this:
int flag;
do{
flag = 1;
cout<<"Input customer's lastname: ";
getline(cin,lname);
if(lname.find_first_not_of( "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ ")!=string::npos)
{
flag = 0;
cout<<"You can only input alpha here!\n";
}
else if(lname.empty())
{
flag = 0;
cout<<"Please enter your firstname!\n";
}
cin.clear();
} while( flag !=1 );
feel free to use a boolean type flag, it doesn't really matter
It seems to me that your code suffers from lack of clarity of purpose.
You apparently don't want the string that's entered to include a leading space, nor multiple consecutive spaces. Other than that, only alphabetic characters should be accepted.
If the user does enter multiple consecutive spaces, I'd probably just ignore all but the first. I'd probably write the code something like this:
#include <string>
#include <iostream>
#include <algorithm>
#include <cctype>
#include <sstream>
bool non_alpha(std::string const &s) {
return !std::all_of(s.begin(), s.end(), [](unsigned char c) { return std::isalpha(c) || std::isspace(c); });
}
std::string get_name(std::string const &prompt) {
std::string result;
std::string line;
do {
std::cout << prompt;
std::getline(std::cin, line);
} while (non_alpha(line));
std::istringstream words(line);
std::string word;
while (words >> word)
result += word + ' ';
return result;
}
int main() {
auto res = get_name("Please enter last name, alpha-only\n");
if (res.empty())
std::cout << "Oh well, maybe some other time";
else
std::cout << "Thanks Mr(s). " << res << "\n";
}
I'd be tempted to consider doing roughly the same for non-alphabetic characters--rather than asking the user to re-enter from the beginning, assume it's a mistake and just ignore it.
Hey i want to stop the user from entering integers when i ask the user to input a name. I have achieved this for an integer and a char. Can anyone help me adapt my code for a string.
int getNum()
{
int num;
std::cout << "\nWhat is your age? ";
while (!(std::cin >> num))
{
// reset the status of the stream
std::cin.clear();
// ignore remaining characters in the stream
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
std::cout << "Enter an *integer*: ";
}
std::cout << "You entered: " << num << std::endl;
return num;
}
char getChar(string q)
{
char input;
do
{
cout << q.c_str() << endl;
cin >> input;
}
while(!isalpha(input));
return input;
}
string q = "This is a test123";
for(string::iterator i = q.begin(); i != q.end(); i++)
{
if((*i < 'A' || *i > 'z') && (*i != ' '))
{
return false;
}
}
would also be an option, if you allow for spaces and other characters.
Edit: updated for checking a single char:
char c;
bool finished = false;
printf("Please enter your sex, M/F?\n");
while(!finished)
{
cin >> c;
if(!(c == 'm' || c == 'M' || c== 'f' || c=='F'))
{
printf("Please try again...\n");
}
else
{
finished = true;
}
}
Note that c is only input, char by char, when Enter is pressed, before that the line feed does not happen.
If you plan on using std:string, then you can use this to find if the entered string has any digits or not:
if (std::string::npos != s.find_first_of("0123456789"))
{
std::cout << "digit(s)found!" << std::endl;
}