I am learning C++, and have been for about 3 weeks now. Right now, I am writing a program based off of a tutorial (don't worry, I know about tutorial hell. I learned the data types and functions one by one before going to tutorials on things I want to learn, like case in point).
So, my question is this - The reason I clicked on this tutorial is because I wanted to learn how to write/read from text files outside of the IDE using ifstream
/ofstream
. However the tutorial is kind of crap and doesn't expand on the specifics.
The program works in the command prompt with 4 different options:
Everything works as intended, and is all really basic and I understand it, EXCEPT THE PART I WANTED TO LEARN IN THE FIRST PLACE.
When clicking "forgot password", it asks the user to enter their username to find their password. If they enter a username that has been registered, it is supposed to give them the password to that username, but instead it gives the most recent password registered.
Now, the interesting thing to me is, you would think since it's not recognizing the password to the username, that would mean the username and password aren't connected and it would allow the user to login with any of the usernames registered and any of the passwords, but that isn't the case.
Is this happening because I have to write code to specify the username and password are linked, like maybe put them in sets when users register, or is it as simple as ifstream
can't read the whole document only the last line and I need to use a different function?
I will post my whole code now, then below I will post the specific function in question. Also, just note that I just gave the variable count
random numbers since the code will change them anyways, and Visual Studio was giving me problems when just initializing without a value.
Code:
#include <iostream>
#include <fstream>
#include <string.h>
#include <cstring>
#include <stdlib.h>
#include <stdio.h>
#include <set>
#include <windows.h>
using namespace std;
//gonna have 3 functions. login, registration, and forgot function with main we will make the menu.
void login();
void registration();
void forgot();
int main() {
int choice;
cout << "\t\t\t\t______________________________________________________\n\n";
cout << "\t\t\t\t Welcome to the login page \n\n\n";
cout << "\t ______________ MENU ________________________________\n\n\n";
cout << "\t| Press 1 to login |" << endl << endl;
cout << "\t| Press 2 to register |" << endl << endl;
cout << "\t| Press 3 if you have forgotten your password. |" << endl << endl;
cout << "\t| Press 4 to EXIT. |" << endl << endl;
cin >> choice;
cout << endl;
switch (choice) {
case 1:
login();
break;
case 2:
registration();
break;
case 3:
forgot();
break;
case 4:
cout << "You have chosen to exit. The program will now close." << endl;
break;
default:
cin.clear();
cin.ignore();
cout << "\aInvalid input! Please try again." << endl;
Sleep(1000);
system("cls");
main();
}
}
void login() {
int count = 5;
string userid, password, id, pass;
system("cls");
cout << "\t\tPlease enter the username and password to the account you would wish to access." << endl;
cout << "\t\t\t USERNAME " << endl;
cin >> userid;
cout << "\t\t\t PASSWORD " << endl;
cin >> password;
ifstream input("records.txt");
while (input >> id >> pass) {
if (id == userid && pass == password) {
count = 1;
system("cls");
}
}
input.close();
if (count == 1) {
cout << userid << " Your login is successful!" << endl;
main();
}
else {
cout << "Username or password was incorrect. Please try again or register if you do not have an account." << endl;
main();
}
}
void registration() {
int count = NULL;
int confirm;
string ruserid, rpassword, rid, rpass;
system("cls");
cout << "You have chosen to register an account. Please type in what you would like for your username." << endl;
cin >> ruserid;
cout << "You have chosen " << ruserid << " as your username. Now please type in what you would like for your password." << endl;
cin >> rpassword;
cout << "You have chosen " << ruserid << " as your username and " << rpassword << " as your password.\nConfirm? yes for yes, no for no." << endl;
cin >> confirm;
switch (confirm) {
case 1: { cout << "You have confirmed this as your account info.\n\n"; break; }
case 2: { cout << "You have cancelled making the account. Returning to registration page.\n"; cin.clear(); cin.ignore(); registration(); break; }
default: { cout << "Invalid input. Returning to registration page.\n"; cin.clear(); cin.ignore(); registration(); break; }
}
/*ifstream input("records.txt");
while(input >> id >> password)
if (ruserid == id) {
cout << "You have picked a username already taken. Please reregister with a different username. Tip: Choose one that is unique." << endl;
cin.clear();
cin.ignore();
system("cls");
registration();
}*/
ofstream f1("records.txt", ios::app);
f1 << ruserid << " " << rpassword << endl;
system("cls");
cout << "Registration successful!\n";
main();
}
void forgot() {
int option;
system("cls");
cout << "You have forgotten the password? Press 1 to search your password by username or 2 to go back to the main menu\n\n";
cin >> option;
switch (option) {
case 1:
{
int count = 0;
string suserid, sid, spass, spassword;
cout << "Please enter your username to regain password.\n\n";
cin >> suserid;
ifstream f2("records.txt");
string line;
while (f2>>sid>>spass) {
if (sid == suserid) {
count = 1;
}
}
f2.close();
if (count == 1) {
cout << "Your account has been found.\n";
cout << "Your password is: " << spass << endl;
}
else {
cout << "User not found. Returning to main menu." << endl;
cin.clear();
cin.ignore();
Sleep(1200);
system("cls");
main();
}
break;
}
case 2:
{
main();
}
default:
{
cout << "Invalid input. Returning to forgot password menu" << endl;
cin.clear();
cin.ignore();
system("cls");
forgot();
}
}
}
The forgot()
function is the one in question, with this specific part that's giving issues:
int count = 0;
string suserid, sid, spass, spassword;
cout << "Please enter your username to regain password.\n\n";
cin >> suserid;
ifstream f2("records.txt");
string line;
while (f2>>sid>>spass) {
if (sid == suserid) {
count = 1;
}
}
f2.close();
if (count == 1) {
cout << "Your account has been found.\n";
cout << "Your password is: " << spass << endl;
}
I have tried making the userid
/id
/pass
/password
as global variables and using them instead of using different ones for each function (though, maybe by using the same variable, it would then know the password that went with the username created).
I have tried adding the variables in all functions as global, but not changing any of the variables in the functions, and just adding an if
statement that says if(sid==suserid){spass==password}
, but this just makes it not output any password.
I have also tried changing the if
statement in the while
loop to if(sid == suserid && spass == password)
.
When you find the corresponding entry, you need to break out of the loop. One way, but maybe not the best, is to do
while (count != 1 && (f2>>sid>>spass)) {
This will stop reading the files once the count has reached one. Note that the count != 1
is before the rest of it, so that it doesn't read the next line.