Output a value to console after do...while statement is satisfied? - c++

I'm extremely new to C++, and can't really figure this out. I've tried a couple things, but I feel like I'm just missing something simple.
I have this console application where a user inputs a pre-defined password. If the password is incorrect, it prompts them to re-enter the password. If the password is correct, is simply ends the program, but I want it to say "Access granted!" then end.
A side issue I'm having is when more than word is entered as the password, "Access Denied" is printed for each word.
string password;
cout << "Please enter the password!" << endl;
cin >> password;
if (password == "test") {
cout << "Access granted!";
} else {
do {
cout << "Access denied! Try again." << endl;
cin >> password;
} while (password != "test");
}
return 0;

You need to output your "Access granted" message after the loop exits, and you also need to clear the stdin input after each failed attempt to discard any words that are still waiting to be read:
#include <limits>
string password;
cout << "Please enter the password!" << endl;
cin >> password;
if (password == "test") {
cout << "Access granted!";
} else {
do {
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');
cout << "Access denied! Try again." << endl;
cin >> password;
} while (password != "test");
cout << "Access granted!";
}
return 0;
Live Demo
Which would be better written like this instead:
#include <limits>
string password;
cout << "Please enter the password!" << endl;
do {
cin >> password;
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');
if (password == "test") break;
cout << "Access denied! Try again." << endl;
}
while (true);
cout << "Access granted!";
return 0;
Live Demo
However, note that operator>> reads only 1 word at a time, so something like "test I GOT IN!" will also be accepted. You should use std::getline() instead to read an entire line at a time, instead of reading a word at a time:
#include <limits>
string password;
cout << "Please enter the password!" << endl;
do {
getline(cin, password);
if (password == "test") break;
cout << "Access denied! Try again." << endl;
}
while (true);
cout << "Access granted!";
return 0;
Live Demo

Related

Elephant SQL with c++ login system

i created a cleint that requires you to register and login to acces certain apps but txt is not a efficent idea especially when i gave it to my friends so am trying to use a online data base but have 0 experince on how to do so so any help would be appreciated try to make words as simple as possiible still a biggener i tried searching online and trying diffrent ways but coudnt find something i could understand ao am still not sure of how to implement this and if its even possible in c++
here is my initial code for login and registering
void login() {
system("color 0B");
int counts = 0;
string userid, password, id, pass;
system("cls");
cout << "\t\t\t Please Enter your username and password : " << endl;
cout << "\t\t\t USERNAME:";
cin >> userid;
cout << "\t\t\t PASSWORD:";
cin >> password;
ifstream input("records.txt");
while (input >> id >> pass) {
if (id == userid && pass == password) {
counts = 1;
system("cls");
}
}
input.close();
if (counts == 1) {
secret(userid);
}
else {
cout << "\nLOGIN ERROR \n Username or password is inccorect\n\n";
main();
}
};
void Register() {
system("color 0B");
system("cls");
string ruserid, rpassword, rid, rpass;
string choice_2;
cout << "\t\t\t Welcome to my application you can register below\n";
cout << "press 1 to register \n";
cout << "press 2 to get back to the main menu \n";
cout << "\t\t\t Enter your option : ";
cin >> choice_2;
if (choice_2 == "1") {
string lock;
cout << "Enter registration password\n";
cout << "input password : ";
cin>>lock;
if (lock == "register_2006") {
system("cls");
cout << "\t\t\t Enter The USERNAME : ";
cin >> ruserid;
cout << "\t\t\t Enter The PASSWORD : ";
cin >> rpassword;
ofstream f1("records.txt", ios::app);
f1 << ruserid << ' ' << rpassword << endl;
system("cls");
cout << "\n\t\t\t Registration is Successful \n";
main();
}
else { cout << "Wrong password please contact to get it\n"; }
main();
}
else if (choice_2 == "2") {
system("cls");
main();
}
else {
cout << "wrong choice try again";
Register();
}
}

C++ ifstream is reading last line only

I am working on a program that allows a user to register an account. When a user registers for an account, the username and password are output to a text file "database.txt".
There is also an option for a user to search for their password by inputing their username if they forget their password. I find that this works fine when there is only one user registered in the .txt file database. However, when there is more than one user, the forgot password function returns the password of the most recent registered user, no matter which username is searched.
database.txt looks like this:
user1 111
user2 222
user3 333
No matter which user is entered to find the password, the function will always return 333, which is the most recent registered user's password. How do I fix this so that whichever user is searched, their password will output?
Here is the function:
void forgot()
{
int ch;
system("cls");
cout << "Forgotten? We're here to help." << endl;
cout << "Choose one of the options below: " << endl;
cout << "1. Forgot my password" << endl;
cout << "2. Forgot my username" << endl;
cout << endl;
cout << "Enter your choice: ";
cin >> ch;
switch(ch)
{
case 1: // search for username to find password
{
int count = 0;
string searchUser, su, sp;
cout << "Enter your username: ";
cin >> searchUser;
ifstream searchUserName("database.txt");
while(searchUserName >> su >> sp)
{
if(su == searchUser)
{
count = 1;
}
}
searchUserName.close();
if(count == 1)
{
cout << "Account found!" << endl;
cout << "Your password is: " << sp;
cin.get();
cin.get();
system("cls");
menu();
}
else
{
cout << "Sorry, that user ID does not exist." << endl;
cout << "Please contact our service team for more details." << endl;
cin.get();
cin.get();
system("cls");
menu();
}
break;
}
case 2: // search for password to find username
{
int count = 0;
string searchPass, su2, sp2;
cout << "Enter your password: ";
cin >> searchPass;
ifstream searchPassword("database.txt");
while(searchPassword >> su2 >> sp2)
{
if(sp2 == searchPass)
{
count = 1;
}
}
searchPassword.close();
if(count == 1)
{
cout << "Your password has been found." << endl;
cout << "Your username is: " << su2;
cin.get();
cin.get();
system("cls");
menu();
}
else
{
cout << "Sorry, we couldn't find your password in our database." << endl;
cout << "Please contact our team for more information." << endl;
cin.get();
cin.get();
system("cls");
menu();
}
break;
}
default:
cout << "Invalid choice, please try again." << endl;
system("cls");
forgot();
}
}
You should break out of the while loop once you have found the user name here:
while(searchUserName >> su >> sp)
{
if(su == searchUser)
{
count = 1;
break; // add this
}
}
Now it will continue to overwrite a previously found user name until searchUserName >> su >> sp is no longer true which is once it encounters EOF in most cases.
The other part of the program has the same problem.
Personnally I would rewrite the code such that the condition whether a matching password has been found or not is part of the loop condition.

getline and while error in C++

Hi I am a beginner for C++, and here is my practice code:
cout << "Hello World! "<< "Please enter your name" << " ";
//cin >> i;
getline(cin, mystring);
stringstream(mystring) >> name;
cout << "Please enter your password"<< " " ;
getline(cin, mystring);
stringstream(mystring) >> password;
cout << password << endl;
do {
cout << "Sorry, your password does not match your name, please enter the password again" << " " << endl;
getline(cin, mystring);
stringstream(mystring) >> password;
} while (!(name == "victor" & password == "victor"));
I wonder why the result is as follows that "Sorry..." appears even the password is correct?
Hello World! Please enter your name victor
Please enter your password victor
victor
Sorry, your password does not match your name, please
enter the password again
A do...while loop always executes at least once because the test at the bottom is performed at the end of the loop.
So you will always see the message about the wrong password at least once. If you want to execute the loop only when the condition is true, use a regular while loop with the condition at the top.
Also, the logic AND operator is && and not &.
while (!(name == "victor" && password == "victor"));
{
cout << "Sorry, your password does not match your name, please enter the password again" << " " << endl;
getline(cin, mystring);
stringstream(mystring) >> password;
}

How should I make my program correctly handle all user inputs?

I want to create an input system that can correctly handle all inputs. The desired user input is an double. When the user inputs a string, the stringstream fails and the exception is handled. However, the program can't handle inputs such as "3245 2345 5" and "21523i4jf", instead of labeling them as improper inputs it registers the number at the beginning of the string and passes that to double number without raising an exception.
while (true)
{
string user_input;
cout << "Your Choice: ";
getline (cin, user_input);
cout << endl;
if (user_input == "quit")
{
break;
}
try
{
double number;
stringstream stringstream_input;
stringstream_input << user_input;
stringstream_input >> number;
if (stringstream_input.fail())
{
throw 90;
}
cout << number << endl << endl;
}
catch (int x)
{
cout << "Please enter a valid input!" << endl << endl;
}
}
You can use std::stod() to handle that correctly.
try {
number = std::stod(user_input);
}
catch(const std::invalid_argument& e) {
std::cerr << "Invalid input '" << user_input << "'" << std::endl;
}

How to stop a while loop

This while loop never ends. For example, when i enter a wrong password it will keep on going to the "incorrect password" part over and over again.
Logo();
inFile.open("UsernamePassword.txt");
if (!inFile)
cout << "Unable to Open File";
else
{
cout << endl << endl << endl;
cout << " Please enter username: ";
cin >> user;
cout << " Please enter password: ";
cin >> pass;
while (username != user)
{
inFile >> username >> password;
if (user == username && pass == password)
{
cout << endl;
cout << "Welcome to CherryLunch!" << endl;
system("pause");
system("cls");
MainMenu();
}
else
{
cout << endl;
cout << " Invalid Username or Password!" << endl << endl;
system("pause");
system("cls");
}
}
}
inFile.close();
The while loop is infinite because you never allow the user to input a new password or username. When the if statement fails, it will return to loop header (where it will still be wrong) and continue onwards.
Give the user a chance to enter in a new user/pass combo and then the loop can still be finite (provided the user eventually provides the correct credentials).
move the cout and cin statements inside the while loop:
else
{
while (username != user)
{
cout << endl << endl << endl;
cout << " Please enter username: ";
cin >> user;
cout << " Please enter password: ";
cin >> pass;
inFile >> username >> password;
if (user == username && pass == password)
{
cout << endl;
cout << "Welcome to CherryLunch!" << endl;
system("pause");
system("cls");
MainMenu();
}
else
{
cout << endl;
cout << " Invalid Username or Password!" << endl << endl;
system("pause");
system("cls");
}
}
}
inFile.close();
It keeps on an infinite loop because you never ask if you reached the end of the file, so, if the file does not contain a username/password combination that matches the pair entered by the user, when the end of the file is reached, the line:
inFile >> username >> password;
Fails and username and password will contain the last entries seen on UsernamePassword.txt and the loop goes forever.
The following implementation of your program will test for the eof in the inFile file object:
#include <fstream>
#include <iostream>
#include <string>
#include <cstdlib>
int main() {
std::ifstream inFile;
std::string user, pass;
std::string username, password;
inFile.open("UsernamePassword.txt");
if (!inFile) {
std::cout << "Unable to Open File";
} else {
std::cout << std::endl << std::endl << std::endl;
std::cout << " Please enter username: ";
std::cin >> user;
std::cout << " Please enter password: ";
std::cin >> pass;
while (username != user && !inFile.eof()) {
inFile >> username >> password;
if (user == username && pass == password) {
std::cout << std::endl;
std::cout << "Welcome to CherryLunch!" << std::endl;
// Equivalent to the 'pause' command in linux
system("read -p 'Press any key to continue...' key");
// Equivalent to the 'cls' command in linux
system("clear");
// MainMenu();
} else {
std::cout << std::endl;
std::cout << " Invalid Username or Password!" << std::endl << std::endl;
system("read -p 'Press any key to continue...' key");
system("clear");
}
}
}
inFile.close();
}
You are trying to check for the username and password from the user and compare with all the usernames and passwords in the file.
Your approach seems fine. But you are printing "Invalid username..." after each comparison, not comparing all the usernames in the file. Hence move this output outside else block and place it in the while loop.
infile checks each line separately.
And also check the end of file.If the username and password are not found till the end of file, then print "Invald username" and provide the user to enter another set of name and password
Hope this helps!!
First, read the correct usernames and passwords from the file and save them in memory. That way, if the username/password validation fails the first time, you don't have to reopen or seek-to-beginning-in the file before checking on the next username/password typed by the user....
std::map usernames_passwords;
std::string username, password;
if (ifstream in("UsernamePassword.txt"))
while (in >> username >> password)
usernames_passwords[username] = password;
else
{
std::cerr << "Unable to open username/password file\n";
exit(EXIT_FAILURE);
}
Then prompt for login details until they're valid:
bool logged_in = false;
while (!logged_in &&
std::cout << "\n\n\n Please enter username: " &&
std::cin >> username &&
std::cout << " Please enter password: " &&
std::cin >> password)
{
// look for a match in the earlier-read login details...
auto it = usernames_passwords.find(username);
logged_in = it != std::end(usernames_passwords) && it->second == password;
}
// the while loop could also exit because "cin >>" failed, indicating EOF
// that could be because the user typed e.g. ^D (UNIX) or ^Z (Windows), or
// input was from a redirected file or pipe or over a network connection...
if (!logged_in)
{
std::cerr << "error reading login details from stdin\n";
exit(EXIT_FAILURE);
}
...ok - we know the username/password are good - do whatever else...