Why is my program not processing all the functions? - c++

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;
}

Related

Why does my code return 0 after entering in username and password for login

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.

Validate input data in an array C++

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

Bool result returns false after reading data from a file

I am trying to learn more about C++ and was given the task of validating a login.
So far I have
#include <iostream>
#include <istream>
#include <fstream>
#include <string>
using namespace std;
void getLogin(string & userName, int password);
bool validateLogin(string userName, int password);
void showResult(bool validation);
int main()
{
int password = 0;
string userName;
bool validation;
getLogin(userName, password);
validation = validateLogin(userName, password);
showResult(validation);
return 0;
}
void getLogin(string & userName, int password)
{
cout << "Enter your ID: ";
cin >> userName;
cout << "Enter your PW: ";
cin >> password;
}
bool validateLogin(string userName, int password)
{
string user;
int pass;
ifstream inFile;
inFile.open("C:\\login.txt");
if (inFile.fail())
{
cout << "Error finding file";
exit(1);
}
getline(inFile, user);
inFile >> pass;
if (userName == user && password == pass)
{
return true;
}
else
{
return false;
}
}
void showResult(bool validation)
{
if (validation == true)
{
cout << "Valid\n\n";
}
else
{
cout << "Invalid\n\n";
}
}
Inside the login.txt file, the username and password are already written. The prompt asks for the user to enter in their username and password. When I enter in the username and password that are inside the txt file, it always shows as invalid. Link to output and login.txt
Assuming you really do want to use an int as a password, the problem is in this function declaration and definition:
void getLogin(string & userName, int password);
Change the password parameter to a reference, similar to the userName parameter and all should be fine. Change the declaration to:
void getLogin(string & userName, int & password);
Then change the definition to match.

How to check if the user had input nothing strings?

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.

Mysterious addition issue [duplicate]

This question already has answers here:
Why does std::getline() skip input after a formatted extraction?
(5 answers)
Closed 7 years ago.
Using the following code in c++:
#include <iostream>
#include <string>
#include <vector>
using namespace std;
class User
{
public:
User();
void setName(string username);
string getName();
private:
string name;
};
User::User()
{}
void User::setName(string username)
{
name = username;
}
string User::getName()
{
return name;
}
class System
{
public:
System();
void createUser();
void postMessage();
string getCurrentUser();
string messageBuffer;
private:
vector<User> users;
string currentUser;
};
System::System()
{
messageBuffer = "";
}
void System::createUser()
{
string username;
bool userExists = false;
cout << "Please enter a user name: ";
cin >> username;
cout << endl;
for(int i = 0; i < users.size(); i++)
{
if(users.at(i).getName() == username)
userExists = true;
}
if(!userExists)
{
User temp; //creates a temporary user stored in vector of Users
users.push_back(temp); //puts new User at end of users
users.back().setName(username);
currentUser = users.back().getName();
}
if(userExists)
cout << "User already exists." << endl << endl;
}
void System::postMessage()
{
string line;
string message;
cout << "Enter message: ";
while(getline(cin,line))
{
if(line == "!!")
break;
message = message + line + "\\n";
}
messageBuffer = "{[" + currentUser + "::tweet]}" + message + messageBuffer;
cout << endl;
}
string System::getCurrentUser()
{
return currentUser;
}
int main()
{
System system;
system.createUser(); //create user named Cam
system.postMessage(); //input message "Hello!"
cout << system.messageBuffer << endl;
return 0;
}
I am outputted with messageBuffer equal to "{[Cam]}\nHello!\n". What I want to happen is messageBuffer to be set to "{[Cam]}Hello!\n". The message inputted can be more than one line long.
Example message input could be:
Hello!
How are you all?
I am great!
!!
messageBuffer should then be:
"{[Cam]}Hello!\nHow are you all?\nI am great!\n"
In actuality I get:
"{[Cam]}\nHello!\nHow are you all?\nI am great!\n"
Where does this mystery "\n" come from?!
This is because you have to flush your stdin buffer before starting to read the messages (you have some unflushed characters which cause getline() to read it and apped \\n to the message string).
In your case I would advice to do it that way:
cin.clear();
cin.ignore(INT_MAX,'\n');
while(getline(cin,line))
if(line == "!!")
break;
message = message + line + "\\n";
}