How I'm I going to add another condition in case the user didn't put anything in both username and password? ( "Empty Username and/or Password - Username and Password required!. Try Again? (Y/N)" )
here's my. code.
#include "stdafx.h"
#include <iostream>;
#include <string>;
using namespace std;
string username;
string password;
string choice;
int main(int argc, const char * argv[])
{
do {
Username:
std::cout << "Enter Username: ";
std::cin >> username;
if (username != "Joven")
{
std::cout << "Invalid Username. Please try again.\n\n\n";
goto choice;
goto Username;
}
Password:
std::cout << "Enter Password: ";
std::cin >> password;
if (password != "Fabricante7188")
{
std::cout << "Invalid Password. Please try again.\n\n\n";
std::cout << "Do you want to try again? y/n \n\n";
cin >> choice;
goto Password;
}
else
{
std::cout << "Correct Username and Password - Log In Successfull.\n";
break;
choice:
std::cout << "Do you want to try again? y/n \n\n";
std::cin >> choice;
}
}while (choice != "y" && choice != "n");
if (choice != "y" && choice != "n")
{
cout << "Invalid choice.\n";
goto choice;
}
system("pause");
return 0;
}`
thanks a lot!
Using the input operation >> you can't. It will block until there is some actual non-space input followed by the Enter key (or there's an error or "end of file").
The C++ standard solution (without resorting to OS specific functionality) is to read a whole like using e.g. std::getline, strip the input of leading (and possibly trailing) spaces, and then see if the resulting string is empty or not.
My solution would be something like this: (Edited by scorch 2017/01/14 10:24 AEST)
//#include "stdafx.h" I made this a comment because I don't appear to have this file. It wasn't necessary for me. Don't know whether you need it or not.
// include statements must not end with semicolons.
#include <iostream>
#include <string>
#include <cstdlib> // Has system() function
using namespace std;
int main(int argc, const char * argv[])
{
// Always declare variables inside the function.
string username;
string password;
string choice;
bool finished = false; // Declare this.
bool askingToTryAgain = false; // For when the user is asked whether they want to try again.
do {
std::cout << "Enter Username: ";
std::getline(std::cin, username);
std::cout << "Enter Password: ";
std::getline(std::cin, password);
// Validate username and password.
if (username != "Joven" && password != "Fabricante7188") {
// If both the username and password are invalid, report it.
std::cout << "Invalid Username and Password. Try again? (y/n): ";
} else if (username == "Joven" && password == "Fabricante7188") {
// If both fields are valid, login is successful.
std::cout << "Correct Username and Password - Log In Successful.\n";
finished = true; // Login is now complete, the loop will end.
} else {
// If just one of the fields is invalid, report which one it is.
if (username != "Joven") {
std::cout << "Invalid Username. Try again? (y/n): ";
}
if (password != "Fabricante7188") {
std::cout << "Invalid Password. Try again? (y/n): ";
}
}
if (finished == false) {
// If the login was unsuccessful, await user input for whether they wish to try again or not.
askingToTryAgain = true;
do {
// Fetch user input (y/n)
std::getline(std::cin, choice);
// Validate it.
if (choice != "y" && choice != "n") {
std::cout << "Enter 'y' or 'n'\n";
} else {
askingToTryAgain = false;
if (choice == "y") {
// Nothing to do here. The parent loop will continue after this one stops.
} else if (choice == "n") {
finished = true; // The user wishes to quit.
}
}
} while (askingToTryAgain);
}
} while (finished == false);
system("pause"); // During testing I used 'sleep 4' (sleep for 4 seconds) because I'm running Linux.
return 0;
}
Also, please do yourself a favour and avoid using 'goto' as a way to control the flow of program execution. Loops and conditions are a far better solution in a structured programming language such as C++ than the 'goto' statements.
I suggest you have a look at http://cplusplus.com/ as a good reference tool.
Hope this helps.
Related
Good day everyone! First off all I want to let you all know that I am a beginner at C++, so my code will have a lot of errors.
I was trying to make a program to refresh my concepts of C++. The problem I am facing is the program is asking me the email ID, but as soon as I input it, the program ends. Please let me know everything I am doing wrong and how to correct it. Thank you so much!
I decided to create a simple login program with the following algorithm:
It asks the user for their email ID.
Checks if the email is registered (in a text file)
If the email is registered, the user is prompted for the password.
If the password is correct, a success message is printed; if not, the user s given 2 more attempts.
If the email is not registered, the program prompts the user to enter a new password and tells them the password strength. An ideal password should have an uppercase letter, a lowercase letter and a digit, with the password length more than 6 characters.
data.h:
#include <iostream>
#include <string>
using namespace std;
#ifndef DATA_H
#define DATA_H
struct newAccount{
string email, password; //declaring email and password of the user
};
string readEmail(string email); //reads in the email id provided
void checkEmail(); //checks if the entered email address exists in the system
int addEmail(); //checks if the entered email address exists in the system
void checkPassword(); //checks if the password matches an already registered email id
void makeNewPassword(string& password); //this function helps the user create a secure password
#endif
data.cpp:
#include <iostream>
#include <string>
#include <fstream>
#include "data.h"
using namespace std;
newAccount tempAccount;
string readEmail(string email) //reads in the email id provided
{
cout << "Enter an email address: ";
getline(cin, tempAccount.email);
email = tempAccount.email;
return tempAccount.email;
}
void checkEmail()
{
ifstream file("database.txt");
string str;
while (getline(file, str))
{
if (str == tempAccount.email)
{
cout << "This email is already registered. Please enter your password: ";
getline(cin, tempAccount.password);
checkPassword();
}
else
{
cout << "This email is not registered. Please create a new password: ";
makeNewPassword(tempAccount.password);
}
}
}
int addEmail() //checks if the entered email address exists in the system
{
ofstream myFile("database.txt");
if (myFile.is_open())
{
myFile << tempAccount.email << endl;
myFile.close();
}
else
cout << "Unable to open file";
return 0;
}
void checkPassword() //checks if the password matches an already registered email id
{
ifstream file("database.txt");
string str;
while (getline(file, str))
{
if (checkEmail)
{
if (str == tempAccount.password)
{
cout << "Login successful! ";
getline(cin, tempAccount.password);
}
else
for (int i = 4; i > 1; i--)
{
cout << "Incorrect password! You have " << i - 1 << " tries remaining.\n";
if (str == tempAccount.password)
break;
}
}
}
}
void makeNewPassword(string &password) //this function helps the user create a secure password
{
int n = password.length();
bool hasLower = false, hasUpper = false, hasDigit = false;
for (int i = 0; i < n; i++)
{
if (islower(password[i]))
hasLower = true;
if (isupper(password[i]))
hasUpper = true;
if (isdigit(password[i]))
hasDigit = true;
}
// Displaying the strength of password
cout << "Strength of password you have entered is ";
if (hasUpper && hasDigit && hasLower && (n >= 6)) // considering a strong must be of length 6 or more
cout << "strong" << endl;
else if ((hasLower || hasUpper) && hasDigit && (n >= 6))
//when at least a lower case or uppercase is used along with digit
cout << "moderate" << endl;
else
cout << "weak" << endl;
}
main.cpp
#include <iostream>
#include <fstream>
#include "data.h"
using namespace std;
int main(){
string e, p;
readEmail(e);
checkEmail();
return 0;
}
I have created this program with the knowledge of a couple of basic C++ courses I took a few semesters ago, and using online tutorials. This is not a homework or an assignment of any kind.
In your readEmail() function, the string email is a local variable. You passed the variable to the function by value, not by reference.
Also, if you pass it by reference, then there's no need to return anything (the function should be void).
void readEmail(string& email) //reads in the email id provided
{
cout << "Enter an email address: ";
cin >> email;
}
int main() {
string e, p;
readEmail(e);
checkEmail();
return 0;
}
But if you want to return the value, than there's no need for parameter, but you need to give that return value to your variable.
string readEmail() //reads in the email id provided
{
cout << "Enter an email address: ";
cin >> email;
return email;
}
int main() {
string e = readEmail();
checkEmail();
return 0;
}
So now whenever i press A or a, it shows the login function however when i type in the correct username or password it returns 0 and i am very lost as to why it happens. It works in python but in c++ i cant get it to work. This is my code... sorry if the code is very hard to understand.
// login system with login and registration and exit
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
char choice;
char return_page;
string username;
string password;
string confirm;
string login_username;
string login_password;
void main_page();
void registration();
void login();
void login()
{
cout<<"Username: ";
cin >> login_username;
cout <<"\nPassword: ";
cin>>login_password;
}
void registration()
{
cout<<"Username: ";
cin>> username;
cout<<"\nPassword: ";
getline(cin, password);
cout << "\nConfirm password: ";
cin >> confirm;
}
void main_page()
{
cout<<"\n\t\t========Login & Registration========\n\n";
cout<<"A.Login\n";
cout<<"B.Registraion\n";
cout<<"C.Exit\n";
cout<<"Please enter which services u would prefer: ";
cin >> choice;
}
int main()
{
main_page();
if(choice == 'C' || choice=='c')
{
return 0;
}
else if(choice == 'B' || choice == 'b')
{
registration();
if(password == confirm)
{
fstream new_file;
new_file.open("registration.txt", ios::out);
if(!new_file){
cout<<"\nCannot register!";
}
else{
new_file<<username;
new_file<<password;
new_file.close();
cout<<"\nRegistration complete";
main();
}
}
else if(password!=confirm)
{
cout<<"\nThe password and confirm password is not the same, type it out again\n";
registration();
}
}
else if(choice =='A' || choice =='a')
{
login();
fstream new_file;
new_file.open("registration.txt", ios::in);
if(!new_file){
cout<<"\nCannot login because of some server issue";
}
else
{
string un;
string pw;
// reading contents of file line by line
getline(new_file,un);
getline(new_file, pw);
if(un == login_username && pw == login_password)
{
return true;
}
else
{
return false;
}
}
}
}
You need to add a newline to separate your username and password like this:
new_file << username << '\n';
new_file << password;
instead of:
new_file << username; // it will concatenate username and password without
new_file << password; // any whitespace or newline in the file
Also, you need to accept the Confirm password correctly, by using getline, the compiler skips it, use std::cin simply to get it.
After this, you'll get rid of your problem.
I'm trying to make a program where you have to login with username (to make it simple i'm first using username, i will add password some time later)
To make it work i want to write the username to a file (which i will encrypt later) and when you want to login, it will check through the file if the username is in fact correct. But when i type in a faulty username, it automatically logs in and dosen't ask to make a new account. Same thing if i do login with the correct username. What am i doing wrong?
(i'm pretty new and this is my first half-decent program so please don't be too harsh if i'm doing something obviously wrong.)
Soo. I did some of those things i understood. This is what i got now:
BUT, now it won't write the new username to the Usernames_and_passwords file.
i am incredibly confused...
#include <iostream>
#include <stdio.h>
#include <algorithm>
#include <string>
#include <fstream>
using namespace std;
string user_input;
string birth_year;
string user_age;
string current_user_profile, current_user_password;
string username, password;
string newprofile;
string makenewusername, makenewpassword;
void TalkToAi() { //VOID TALKTOAI
while (true) {
cout << "write something: ";
cin >> user_input;
transform(user_input.begin(), user_input.end(), user_input.begin(), ::tolower); //TRANSLATES ALL UPPERCASE LETTERS TO LOWER CASE SO THE SYSTEM CAN UNDERSTAND!
cout << user_input << "\n"; //###FOR TESTING PORPOSES!!!###
//IF LIBRARY!
if (user_input == "what's my age?" || user_input == "count my age" || user_input == "whats my age?") {
//###CONTINUE HERE!!!###
}
}
}
void StartUp() { //VOID UPONSTARTUP (WHAT TO DO, ALSO READS DIFFRENT PROFILES AND PASSWORDS FOR LOGIN)
cout << "what profile should i load?" << "\n" << "profile name: ";
cin >> current_user_profile;
fstream Myfile;
Myfile.open("Usernames_and_passwords.txt");
if (Myfile.is_open()) {
while (getline (Myfile, username) ) {
if (username == current_user_profile) {
cout << "\n" << "Hello, " << username << "\n";
break;
}
}
if (username != current_user_profile) {
cout << "wrong username or username unfortunately not found.\n";
cout << "shall i create a new profile? Yes/No: ";
cin >> newprofile;
if (newprofile == "Yes" || newprofile == "yes") {
cout << "new profile username: ";
cin >> makenewusername;
Myfile << makenewusername << endl;
}
}
}
}
It won't write to the file because once you finish reading the file with getline(), the eof flag will be set. You need to open the file using:
Myfile.open("Usernames_and_passwords.txt",fstream::in | fstream::out | fstream::app);
This tells the program to open the file for reading and writing. fstream::app tells the program to append text to the end of the file.
Then, in order to reset once an eof has been hit you can do
Myfile.clear();
Myfile.seekg(0, ios::beg);
This will clear the eof flag, and move the pointer back to the beginning of the file.
After this you can write to the file.
A few other remarks:
Your loop is broken: it won't work if the file is empty and it will write duplicate usernames if the entered username is on the second line instead of the first.
Here is a modified version of your function:
void StartUp() { //VOID UPONSTARTUP (WHAT TO DO, ALSO READS DIFFRENT PROFILES AND PASSWORDS FOR LOGIN)
cout << "what profile should i load?" << "\n" << "profile name: ";
cin >> current_user_profile;
fstream Myfile;
Myfile.open("Usernames_and_passwords.txt",fstream::in | fstream::out | fstream::app);
if (Myfile.is_open()) {
while (getline (Myfile, username) ) {
if (username == current_user_profile) {
cout << "\n" << "Hello, " << username << "\n";
return;
}
}
cout << "wrong username or username unfortunately not found.\n";
cout << "shall i create a new profile? Yes/No: ";
cin >> newprofile;
if (newprofile == "Yes") {
cout << "new profile username: ";
cin >> makenewusername;
Myfile.clear();
Myfile.seekg(0, ios::beg);
Myfile << makenewusername << endl;
}
}
}
I would also suggest to let StartUp return a boolean value on whether or not the operation succeeded, so you can decide to terminate the program. E.g. if the user entered "No".
I have this program that i took it out from: https://intcpp.tech-academy.co.uk/input-validation/ and it works fine, i did some changes because i need the program to keep asking the user to enter a valid input, so that why it has the while in there however it only asks 4 times after that 4th time the input will be valid it does not matter if it right or not, Does any one know how i can fix this. Thank you
#include <iostream>
#include <string>
#include <cctype>
using namespace std;
int main () {
cout << "Please enter name:" << endl;
string userName;
getline(cin, userName);
bool rejected = false;
while (rejected == false)
{
for (unsigned int i = 0; i < userName.length() && !rejected; i++)
{
if (isalpha(userName[i]))
continue;
else if (userName[i] == ' ')
continue;
else
{
cout << "Error, Please enter Patient's name again, First Name: ";
getline(cin, userName);
rejected = false;
}
}
rejected = true;
}
system("pause");
return 0;
}
Personally I would do something like
bool is_valid_username(std::string const& username)
{
// First trim the string of all leading and trailing white-space
trim(username);
if (username.length() == 0)
return false; // Input was empty or all spaces
return std::all_of(begin(username), end(username), [](char const ch)
{
return std::isalpha(ch) || ch == ' '; // Only letters and spaces are allowed
});
}
std::string get_username()
{
std::string username;
do
{
std::cout << "Please enter username: ";
std::getline(std::cin, username);
} while (!is_valid_username(username));
return username;
}
[For the trim function please see this old answer]
The get_username function will continue to ask for a username forever if the input is either empty, all spaces, or contains non-letters or not a space.
Here's a reference for std::all_of.
Here's a reference about lambda expressions.
if (isalpha(userName[i]) || (userName[i] == ' '))
continue;
else
{
cout << "Error, Please enter Patient's name again, First Name: ";
getline(cin, userName);
i = -1; //Reset check name
}
Try it!
Change unsigned int to int
I am writing a database program with many features (Read, write, delete, search, login ect. ) and my writing feature just stopped working (It was working 3 days ago) and I have no idea what changed. My writing function (void savescore) is supposed to write my input (cin username and password) and then move to the next line so I can input some more info the next time I decide to go and write to the file. Right now it's just writing over what I last put in.
test2.txt -
Username, Password
Then I go to edit and enter "User, Pass" and this is what happens
test2.txt - User, Pass
I want it to enter that on the next line and I did "\n" Can someone give me some help? Thanks
CODE:
#include <iostream>
#include <stdlib.h>
#include <windows.h>
#include <fstream>
#include <conio.h>
#include <string>
#include <math.h>
using namespace std;
// Variables
string username;
string password;
//alphabet order functions
// Functions
void SaveScore()
{
ofstream Database;
Database.open("test2.txt");
Database << username << " " << password << "\n";
Database.seekp(0,std::ios::end); //to ensure the put pointer is at the end
Database.close();
}
int main()
{
int db;
char ans;
string save;
string file;
ifstream fin;
ofstream fout;
string searchpar;
char repeat;
bool loop = true;
while (loop == true)
{
cout << "WELCOME TO MY DATABASE\n\n";
cout << "To view the database, press 1\nTo edit the database, press 2\nTo search the database, press 3\nTo log in, press 4\n";
cin >> db;
system("CLS");
if (db == 1)
{
cout << "Here is the database: \n\n";
string line;
ifstream myfile("test2.txt");
if (myfile.is_open())
{
while (getline(myfile, line))
{
cout << line << '\n';
}
}
//open while bracket
cout << "\n\nWould you like to return to the menu(y/n)?";
cin >> repeat;
if (repeat == 'y')
{
loop = true;
}
else if (repeat == 'n')
{
loop = false;
}
system("CLS");
}
else if (db == 2)
{
cout << "Please enter your username : ";
cin >> username;
cout << "\nPlease enter your password: ";
cin >> password;
SaveScore();
cout << "\n\nWould you like to return to the menu(y/n)?";
cin >> repeat;
if (repeat == 'y')
{
loop = true;
}
else if (repeat == 'n')
{
loop = false;
}
system("CLS");
}
}
}
You say your program is
replacing the first line of the text file everytime I try to write something new into it
As it turns out, that's exactly what you have asked it to do. Consider:
Database << username << " " << password << "\n";
Database.seekp(0,std::ios::end); //to ensure the put pointer is at the end
You are opening the file (when the write pointer starts at the start of the file, writing some data, and then seeking to the end. Seeking to the end does not change the fact that you've already written the text. Swap the order of the above lines to get what you want.
Alternatively, you can open the file in "append" mode using:
Database.open("test2.txt", std::ios::app);
In this situation, you can omit the call to seekp entirely, since all data will automatically be written to the end of the file. See http://en.cppreference.com/w/cpp/io/basic_ofstream/basic_ofstream for full documentation on this.