I'm trying to have user login and registration system using binary files to save the data, and check if username and password are equal to those saved. It seems to work fine when Create_Login() and Write() are called and even when Login() is called after. The problem occurs when Login() is called by itself. The Exception gets thrown when it try's to read username and password. I've been trying to fix this for a while now and just cant see it. Any help would be appreciated
Here is my code
Main.cpp
int input;
cin >> input;
switch (input) {
case 1:
file.Login("");
break;
case 2:
file.Create_Login();
break;
}
.h file
struct Files {
char username[50];
char password[50];
string CheckPassword;
string CheckUsername;
public:
void Write(string name);
void Login(string name);
void Create_Login();
Files();
~Files();
public:
ifstream ReadFile; // Read
ofstream WriteFile; // Write
};
.cpp file
Files::Files() {}
void Files::Login(string name) {
cout << "\nEnter Username: " << flush; cin >> CheckUsername;
cout << "Enter Password: " << flush; cin >> CheckPassword;
name = CheckUsername;
ReadFile.open(name + ".bin", ios::out | ios::binary);
cout << "Your Username is: " << CheckUsername << ", " << "Your Password is: " << CheckPassword << endl; // debug line
if (ReadFile.is_open()) {
cout << "Opened file " + name + ".bin" << endl;
ReadFile.read(reinterpret_cast<char*>(&username), sizeof(Files)); //Execption Thrown Here!!!!!
ReadFile.read(reinterpret_cast<char*>(&password), sizeof(Files));
if (CheckUsername == username && CheckPassword == password) {
cout << "Access Granted" << endl;
}
else if (CheckUsername != username && CheckPassword != password) {
cout << "Access Denined" << endl;
}
else {
cout << "Error!!!" << endl;
}
}
else {
cout << "Could not open file: " + name << endl;
cout << "File does not exist" << endl;
}
}
void Files::Create_Login() {
cout << "Create UserName >> " << flush; cin >> username;
cout << "\nCreate Password >> " << flush; cin >> password;
Write(username);
}
void Files::Write(string name) {
WriteFile.open(name + ".bin", ios::binary);
if (WriteFile.is_open()) {
WriteFile.write(reinterpret_cast<char*>(&username), sizeof(Files));
WriteFile.write(reinterpret_cast<char*>(&password), sizeof(Files));
WriteFile.close();
}
else {
cout << "could not create file: " << name + ".bin" << endl;
}
Login(username);
}
Files::~Files() {
cout << "Destructor Called" << endl;
ReadFile.close();
}
Exception resolved. by changing
ReadFile.read(reinterpret_cast<char*>(&username), sizeof(Files));
ReadFile.read(reinterpret_cast<char*>(&password), sizeof(Files));
to
ReadFile.read(reinterpret_cast<char*>(&username), sizeof(username));
ReadFile.read(reinterpret_cast<char*>(&password), sizeof(password));
thanks for the info
Related
I've been attempting this for awhile but I keep getting lost the more I look into it.
I've been attempting to create a system which allows a user to input their sign up details, have them stored in a file, then later have a login which validates that file.
So far, I've come up with some code, but it's like it's only reading the start of the file and only validating that. I know it shouldn't work, but I don't know how to go about fixing it.
#include <iostream>
#include <string>
#include <fstream>
#include <string.h>
using namespace std;
class file {
private:
string Name, password;
string ID;
public:
void Display();
int Menu();
void addtofile();
void VerifyPass();
};
int main()
{
file Obj;
Obj.Menu();
Obj.Display();
Obj.addtofile();
Obj.VerifyPass();
}
int file::Menu() // The
{
int Option = 0;
attemp:
system("cls");
cout << "1: Sign u " << endl;
cout << "2: Login: " << endl;
cout << "3: Exit" << endl;
cout << "Select Option: " << endl;
cin >> Option;
switch(Option)
{
case 1:
addtofile();
break;
case 2:
VerifyPass();
break;
case 3:
exit(0);
break;
default:
cout << "Wrong Input, attempt again";
goto attemp;
}
return 0;
}
void file::addtofile() // Sign up pag:
{
// system("cls");
ofstream File("Test.txt");
cout << "Sign Up: \n \n \n";
cout << "Enter Name: ";
cin >> Name;
File << Name << endl;
cout << "Enter Password: ";
cin >> password;
File << password << endl;
cout << "Enter ID: ";
cin >> ID;
File << ID << "\n";
File.close();
// cout << "Finished" << endl;
// system("cls"); //
Menu();
}
void file::VerifyPass() // For verifying the user has inputted the correct information
{
string line1;
string PasswordInput2;
string NameInput2;
string IDInput2;
bool IsNamevalid = false;
bool IsIDvalid = false;
bool IsPassvalid = true;
do {
ifstream input("Test.txt", ios::app); // Iosapp is from my understanding, a pointer which allows the program to navigate a file.
system("cls");
cout << "Login: \n";
cout << "Enter Name: " << endl;
cin >> NameInput2;
cout << "Enter Password: " << endl;
cin >> PasswordInput2;
cout << "Enter ID: " << endl;
cin >> IDInput2;
while (!input.eof())
{ // eof is end of file
getline(input, line1);
if (NameInput2 == line1)
{
IsNamevalid = true;
}
if (PasswordInput2 == line1)
{
IsNamevalid = true;
}
if (IDInput2 == line1)
{
IsIDvalid = true;
}
input.close();
}
if (IsNamevalid == false)
{
cout << "Wrong Name , please attempt again" << endl;
input.close();
system("pause");
}
if (IsPassvalid == false)
{
cout << "Wrong Password, Please attempt again" << endl;
input.close();
system("pause");
}
if (IsIDvalid == false)
{
cout << "Invalid ID, please attempt again" << endl;
system("pause");
}
else
{
"Login Successful";
}
} while (IsNamevalid, IsPassvalid, IsIDvalid == false);
system("pause");
}
void file::Display() // just displays what the user inputted for the sign up page
{
system("cls");
string text;
ifstream Readfile("Test.txt");
while (getline(Readfile, text))
{
cout << text << endl;
}
Readfile.close();
cout << "Click to continue to Menu" << endl;
system("pause");
Menu();
}
There are a lot of problems with your code.
main() should not be calling addtofile() and VerifyPass() since those are called inside of Menu().
Menu() should use a do..while loop instead of goto.
VerifyPass() using !eof() in a loop is wrong (Display() loops correctly).
addtofile() is not specifying any flags when opening the file, so it wipes out the existing data. You need to specify the ios::app flag to preserve any existing data. Using ios::app on an ifstream, as you are currently doing in VerifyPass(), is wrong. ios::app is an output-only flag, so it should be used on the ofstream in addtofile() instead.
addtofile() adds 3 new lines to the file per entry, but VerifyPass() only reads in and validates 1 line at a time. You need to read in 3 lines at a time and validate them together as a whole.
With that said, try something more like this instead:
#include <iostream>
#include <string>
#include <fstream>
#include <limits>
#include <cstdlib>
using namespace std;
class file {
public:
void Display();
void Menu();
void AddToFile();
void VerifyPass();
};
int main()
{
file Obj;
do
{
Obj.Menu();
Obj.Display();
}
while (true);
}
void file::Menu()
{
int Option = 0;
system("cls");
do
{
cout << "1: Sign u " << endl;
cout << "2: Login: " << endl;
cout << "3: Exit" << endl;
cout << "Select Option: " << endl;
cin >> Option;
cin.ignore(numeric_limits<streamsize>::max(), '\n');
switch (Option)
{
case 1:
AddToFile();
return;
case 2:
VerifyPass();
return;
case 3:
exit(0);
return;
default:
cout << "Wrong Input, try again" << endl;
break;
}
}
while (true);
}
void file::AddToFile()
{
ofstream File("Test.txt", ios::ate);
if (!File.is_open())
{
cout << "Can't open/create file" << endl;
system("pause");
return;
}
string Name, Password, ID;
cout << "Sign Up: \n \n \n";
cout << "Enter Name: ";
getline(cin, Name);
File << Name << '\n';
cout << "Enter Password: ";
getline(cin, Password);
File << Password << '\n';
cout << "Enter ID: ";
getline(cin, ID);
File << ID << '\n';
File.close();
cout << "Finished" << endl;
system("pause");
}
void file::VerifyPass()
{
string line1, line2, line3;
string PasswordInput;
string NameInput;
string IDInput;
bool IsNamevalid = false;
bool IsIDvalid = false;
bool IsPassvalid = false;
ifstream input("Test.txt");
if (!input.is_open())
{
cout << "Can't open file" << endl;
system("pause");
return;
}
system("cls");
cout << "Login: \n";
cout << "Enter Name: " << endl;
getline(cin, NameInput);
cout << "Enter Password: " << endl;
getline(cin, PasswordInput);
cout << "Enter ID: " << endl;
getline(cin, IDInput);
while (getline(input, line1) &&
getline(input, line2) &&
getline(input, line3))
{
if (NameInput == line1)
{
IsNamevalid = true;
if (PasswordInput == line2)
{
IsPassvalid = true;
if (IDInput == line3)
{
IsIDvalid = true;
break;
}
}
}
}
input.close();
if (!IsNamevalid)
{
cout << "Wrong Name, please try again" << endl;
}
else if (!IsPassvalid)
{
cout << "Wrong Password, please try again" << endl;
}
else if (!IsIDvalid)
{
cout << "Invalid ID, please try again" << endl;
}
else
{
cout << "Login Successful";
}
system("pause");
}
void file::Display()
{
system("cls");
string text;
ifstream Readfile("Test.txt");
while (getline(Readfile, text)) {
cout << text << endl;
}
Readfile.close();
system("pause");
}
my program of registration and login encountered a few problems during output :
I have to register a new user and pass first(even if i alrd have previous usernames and passwords stored in the text file im trying to retrieve it from), after that only i can login using previous username and passwords and this repeats after i close the debug window and start debugging again (if i directly choose to login upon running the program, it will output "invalid username or password")
when logging out from a newly registered username, the program jumps to the
int main() AND DISPLAY "1. Register...."
but logging out from previous usernames, it jumps to
void login() and display "Username:"
*note: the last function isn't complete yet but i think it doesn't affect it (?) (the program worked fine before i added the void accountPage()tho)
*i am not supposed to use pointers plus i'm very new to c++
the code is a bit long but its just a lot of simple functions, i would rly appreciate it if someone can point out my mistake anywhere
#include <iomanip>
#include <cctype>
#include <fstream>
#include <string>
using namespace std;
//Global Variables
int Choice1;
int mobile, ic;
string user, pass, name, inUser, inPass;
//Function Prototypes
void register_user();
void login();
void bookRoom();
bool CheckCredentials(string, string);
void accountPage();
int main()
{
cout << "Welcome to Cozy Homes!\n";
cout << "Operating hours: 11am - 10pm Tuesday - Sunday\n\n\n\n";
do {
cout << "\n1. Register\n";
cout << "2. Log In\n";
cout << "3. Exit\n";
cout << "Please enter a number:";
cin >> Choice1;
if (Choice1 == 1)
{
register_user();
}
else if (Choice1 == 2)
{
login();
}
else if (Choice1 == 3)
{
cout << "Exiting now...\n";
return 0;
}
else if (Choice1 < 1 || Choice1 > 3)
{
cout << "Please choose a number from the menu!" << endl;
}
} while (Choice1 != 3);
system("pause");
return 0;
}
//Register page
void register_user()
{
cin.ignore();
cout << "\n\n\n" << "New Username: ";
getline(cin, user);
cout << endl;
cout << "New Password: ";
getline(cin, pass);
cout << endl;
cout << "Full name: ";
getline(cin, name);
cout << endl;
cout << "Mobile Number: ";
cin >> mobile;
cout << endl;
cout << "Ic Number (without \" - \"): ";
cin >> ic;
cout << endl;
cout << "Registered Successfully!" << endl;
cout << endl;
//Store username and password in login file
ofstream l("login.txt", ios::app);
if (!l.is_open()) {
cout << "could not open file \n";
}
l << user << " " << pass << endl;
l << endl;
l.close();
//Store other details in customer file
ofstream c("customer.txt", ios::app);
if (!c.is_open()) {
cout << "could not open file \n";
}
c << user << endl;
c << pass << endl;
c << name << endl;
c << mobile << endl;
c << ic << endl;
c << '\n';
c.close();
}
//Log in page
void login()
{
do
{
cout << "\nUsername: ";
cin >> inUser;
cout << "Password: ";
cin >> inPass;
if (CheckCredentials(inUser, inPass) == true)
{
cout << "\nLogin sucessful!" << endl;
cout << "Welcome, " << inUser << endl;
cout << endl;
accountPage(); // Redirects user to their account page after successfully logged in
}
else
cout << "\nInvalid username or password. " << endl;
} while (CheckCredentials(inUser, inPass) != true);
}
//Validate their username and password
bool CheckCredentials(string inUser, string inPass)
{
string u;
string p;
bool status = false;
ifstream f;
f.open("login.txt");
if (!f.is_open())
{
cout << "Unable to open file!\n";
}
else if (f)
{
while (!f.eof())
{
f >> u >> p;
if (inUser == u && inPass == p)
{
status = true;
}
else
{
status = false;
}
}
}
f.close();
return status;
}
//Account Page
void accountPage()
{
int Choice2;
do
{
cout << "1. Profile\n";
cout << "2. Book a Room\n";
cout << "3. Cancel Booking\n";
cout << "4. Logout\n";
cout << "Please enter a number: ";
cin >> Choice2;
if (Choice2 == 1)
{
}
else if (Choice2 == 2)
{
}
else if (Choice2 == 3)
{
}
else if (Choice2 == 4)
{
cout << "Logging out.....\n\n\n\n";
cout << endl;
}
} while (Choice2 != 4);
}
//Booking page
void bookRoom() {
cout << " ";
}
```
Like this :
void login()
{
bool loggedin = false;
while(!loggedin)
{
cout << "\nUsername: ";
cin >> inUser;
cout << "Password: ";
cin >> inPass;
if (CheckCredentials(inUser, inPass) == true)
{
loggedin = true;
cout << "\nLogin sucessful!" << endl;
cout << "Welcome, " << inUser << endl;
cout << endl;
accountPage(); // Redirects user to their account page after successfully logged in
}
else
cout << "\nInvalid username or password. " << endl;
}
}
or like this:
void login()
{
bool loggedin = false;
do
{
cout << "\nUsername: ";
cin >> inUser;
cout << "Password: ";
cin >> inPass;
if (CheckCredentials(inUser, inPass) == true)
{
loggedin = true;
cout << "\nLogin sucessful!" << endl;
cout << "Welcome, " << inUser << endl;
cout << endl;
accountPage(); // Redirects user to their account page after successfully logged in
}
else
cout << "\nInvalid username or password. " << endl;
}
while(!loggedin)
}
As this is a school assignment I did not bother to test the code myself.
It is just meant to get you futher and I did only minimal changes.
The point of your error is that the faulty function calls checkcredentials before a user and pasword is entered in the system.
If this solves your problem please mark as solution.
l << user << " " << pass << endl;
l << endl; <---- creates an empty line in your file. Is this intentional ?
l.close();
Clearly there is more bugs in your program. But this will get you further.
Have to do my own job now ;-)
bool UserDeatiles::loginUser(){
string vEmail,vPasswd;
UserDeatiles trm;
ifstream fin("User.txt" , std::ios::in);
if(!fin.is_open()){
//throw CustomException(fin , "File could not be opened ");
cout << "File could not be opened." << endl;
exit(1);
}
cout << "Enter the valid username : ";
cin >> vEmail;
cout << "Enter the password : ";
cin >> vPasswd;
while(fin.read((char*)&trm , sizeof(trm))){
if(vEmail.compare(trm.returnEmail()) == 0 && vPasswd.compare(trm.returnPasswd())==0){
cout << "Wellcome " << trm.name << endl;
fin.close();
//trm.clear();
return true;
}
//fin.read((char*)&trm , sizeof(trm));
}
if(fin.bad()){
cout << "Error in file operation." << endl;
exit(1);
}
cout << "Invalid Login credentials !.." << endl;
fin.close();
return false;
}
In the above login function gives the segmentation fault after it successfully return to main function in main function here is where it loginUser() returns to main
switch (choice){
case 1 : loginCheck = temp.loginUser();
if(loginCheck){
cout << "you are login successfully .!";
}else{
cout << "If you don't have any account sighup " << endl;
}
break;
I stuck here can u please help me .
This question already has answers here:
How to stop a while loop
(5 answers)
Closed 8 years ago.
In my text file ("UsernamePassword.txt"), there are multiple lines of Usernames and Passwords. When I tried logging in using the Username and Password on the 2nd line or 3rd line, it brings me to the "invalid username or password" part. Only the 1st line of username and password works.
Any suggestion on how to read the multiple lines?
{
fstream inFile;
string user, pass, username, password;
int choice;
Logo();
cout << endl << endl << endl;
inFile.open("UsernamePassword.txt");
if (!inFile)
cout << "Unable to Open File";
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)
{
system("cls");
cout<<endl<<endl<<endl<<endl<<endl<<endl<<endl<<endl<<endl;
cout << "\t ****************************************** " << endl;
cout << "\t ** !!! Welcome to CherryLunch !!! ** " << endl;
cout << "\t ****************************************** " << endl;
cout<<endl<<endl<<endl<<endl<<endl;
system("pause");
system("cls");
MainMenu();
}
else
{
cout<<endl<<endl<<endl<<endl<<endl;
cout << "\t !!! Invalid Username or Password !!!" << endl<<endl;
cout << "\t *** Please try again ***" << endl;
cout<<endl<<endl<<endl<<endl<<endl;
system("pause");
system("cls");
}
}
}
inFile.close();
}
You haven't given us the whole code - but I have placed comments in your code (various places) to indicate whether you wanted to do this willingly or did it by mistake:
{
fstream inFile;
string user, pass, username, password;
int choice;
Logo();
cout << endl << endl << endl;
inFile.open("UsernamePassword.txt");
if (!inFile)
cout << "Unable to Open File";
else
{
while (username != user) // Only the following run will repeat ( if this is the intention?)
cout << endl << endl << endl;
cout << " Please enter username: ";
cin >> user;
cout << " Please enter password: ";
cin >> pass;
{ // This is scoped operation
inFile >> username >> password;
if (user == username && pass == password)
{
system("cls");
cout<<endl<<endl<<endl<<endl<<endl<<endl<<endl<<endl<<endl;
cout << "\t ****************************************** " << endl;
cout << "\t ** !!! Welcome to CherryLunch !!! ** " << endl;
cout << "\t ****************************************** " << endl;
cout<<endl<<endl<<endl<<endl<<endl;
system("pause");
system("cls");
MainMenu();
}
else
{
cout<<endl<<endl<<endl<<endl<<endl;
cout << "\t !!! Invalid Username or Password !!!" << endl<<endl;
cout << "\t *** Please try again ***" << endl;
cout<<endl<<endl<<endl<<endl<<endl;
system("pause");
system("cls");
} // End of inner else
} // This is the end of scoped operation
} // End of Outer else
inFile.close();
This is my code:
`
void Customer::validate_cust_username_and_password()
{
string uname, pword;
cout << "enter name: " << endl;
cin >> uname;
cout << "enter password: " << endl;
cin >> pword;
ifstream myfile("cust_username_and_password.txt");
if (myfile.is_open())
{
while (!myfile.eof())
{
if (uname == cust_username && pword == cust_password)
{
cout << "Login successfully." << endl;
cust_mainmenu();
break;
}
else
{
cout << "Wrong username or password!" << endl;
break;
}
}
myfile.close();
}
}
`
This is another code which store the username and password:
`void Customer::cust_register_name_and_password()
{
string un, pw;
ofstream myfile("cust_username_and_password.txt", ios::out | ios::app);
cout << "Enter Customer Username= " << endl;
getline(cin, un);
cout << "Enter Customer Password= " << endl;
getline(cin, pw);
myfile << endl << un << " " << pw << endl;
myfile.close();
cout << "Register Successfully." << endl;
system("pause");
}`
So the problem is when I enter the username and password which I already stored in the text file before, the output is only showing the "Wrong username or password!".
Really appreciate if anyone can help.
In your validate_cust_username_and_password function, you never read in the username and password. Add this:
myfile >> cust_username >> cust_password;
cust_username and cust_password are never set anywhere in this code, so they will never match the user's input (unless the user enters empty strings).
string uname, pword;
cout << "enter name: " << endl;
cin >> uname;
cout << "enter password: " << endl;
cin >> pword;
ifstream myfile("password.txt");
if (myfile.is_open())
{
while (!myfile.eof())
{
if (uname == "test" && pword == "0000")
{
cout << "Login successfully." << endl;
cust_mainmenu();
break;
}
else
{
cout << "Wrong username or password!" << endl;
break;
}
}
myfile.close();
}
}
Where did cust_username magically appear. Was Paul Daniels involved. Paul I take that back you are not as bad as David Blaine - but not a lot