c++:reading from file/parse string - c++

I am currently working on a program, where the user of the program is required to input username and password, and the program will do the search and see if there is such user, if it exists, then proceeding to a screen with further options, or reenter the username.
The username.txt files that stores the username and password includes the following data:(first column is username, and second is password)
john,abc
marry,cde
admin,admin
joseph,1234
My code is as follows, but it doesnt work, after i input username and password, the programs automatically closes. Can you help me with it? Is there something wrong with my parsing the string into 2?
#include<iostream>
#include<fstream>
#include<sstream>
#include<string>
#include<math.h>
#include<stdio.h>
using namespace std;
void printoptionsadmin(){
cout << "Please select an option:" << endl;
cout << "1.Sell Stock\n2.Buy stock\n3.Inquiry\n4.Logout\n5.Shutdown" << endl;
}
void printoptions(){
cout << "Please select an option:" << endl;
cout << "1.Sell Stock\n2.Buy stock\n3.Inquiry\n4.Logout" << endl;
}
void main()
{
cout << "Please login." << endl;
stop:
string usertype;//user input
string passtype;//user input
string line;
string manager = "admin";
string managerp = "admin";
string user;//read from file
string pass;//read from file
ifstream openfile("username.txt");
cout << "Enter your username:";
cin >> usertype;
cout << "Enter your password:";
cin >> passtype;
bool found = false;
while (found&&getline(openfile, line))
{
stringstream iss(line);
getline(iss, user, ',');
getline(iss,pass);
if (usertype == manager && passtype == managerp)//admin login
{
void printoptionsadmin();
found = true;
break;
}
else if (usertype== user && passtype== pass)//regular login
void printoptions();
else
{
cout << "Invalid username or password, please start over." << endl;
goto stop;//going back to login screen
}
openfile.close();
}
}

I altered your code a bit, you messed up the found, plus i removed the goto, also you don't have to explicitly close the file, it is closed when the scope is left(RAAI).
I suggest you to add some checks to your code (file ok? read of line ok? ...)
#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
using namespace std;
static const string PASSWORD_FILE("username.txt");
static const string MANAGER_USER = "admin";
static const char DELIM = ',';
void printoptionsadmin() {
cout << "Please select an option:" << endl;
cout << "1.Sell Stock\n2.Buy stock\n3.Inquiry\n4.Logout\n5.Shutdown"
<< endl;
}
void printoptions() {
cout << "Please select an option:" << endl;
cout << "1.Sell Stock\n2.Buy stock\n3.Inquiry\n4.Logout" << endl;
}
string login() {
ifstream passwordFile(PASSWORD_FILE);
string usertype; //user input
string passtype; //user input
cout << "Enter your username:";
cin >> usertype;
cout << "Enter your password:";
cin >> passtype;
for (string userPasswordLine; getline(passwordFile, userPasswordLine);) {
stringstream ss(userPasswordLine);
string user, password;
getline(ss, user, DELIM);
getline(ss, password, DELIM);
if (user == usertype && password == passtype) {
return user;
} // if
} // for
return "";
}
int main() {
cout << "Please login." << endl;
string loggedInUser;
while ((loggedInUser = login()) == "") {
cerr << "Login failed" << endl;
} // while
if (loggedInUser == MANAGER_USER) {
printoptionsadmin();
} else {
printoptions();
} // else
return 0;
}

Each getline() without third parameter will read a new line and it will provide you something that you are not needed here.
So use " " white space as the delimiter in getline() function instead of default "\n".
Also another thing is your while loop condition is always false since found is initialized to false. So it will not go inside while loop
Here is the logic you needed,
bool found = false;
while (found&&getline(openfile, line))
bool found = false;
std::string delimiter = ",";
while (getline(openfile, line, " "))//To read upto each " "(white space instead of next line(\n is default third parameter)
{
/* Splitting the UserName & Password using ','*/
user = line.substr(0, line.find(delimiter));
pass = line.substr(line.find(delimiter)+1, -1);
if (usertype == manager && passtype == managerp)//admin login
{
void printoptionsadmin();
found = true;
break;
}
else if (usertype== user && passtype== pass)//regular login
void printoptions();
else
{
cout << "Invalid username or password, please start over." << endl;
goto stop;//going back to login screen
}
openfile.close();
}

Related

Getting the input from the file as string and also integer C++

I have a text file. I have a text file consisting of member data. I am developing a program where we can get the member data from the file. After searching in the internet, I have searched a way to read all the data from the file as char array. But I want to change it where upon reading from file I want the data to be string and also integer.
name, icno, email, phone_number, acc_num, password ( read from file AS STRING )
month, year ( read from file AS INTEGER )
Content of Membership.txt
Mathavan|021127100897|MathavanKrishnan27#gmail.com|0167750575|1410065449|Mathavan1234|3|2022
Mathavan|021127100897|MathavanKrishnan27#gmail.com|0167750575|1410065448|Mathavan1234|3|2024
Mathavan|021127100897|MathavanKrishnan27#gmail.com|0167750575|1410065447|Mathavan1234|3|2022
string member_login(){
title();
fstream member;
member.open("Membership.txt",ios::in);
string pass_input, line, acc_num1, password1;
int login_attempt = 0, count = 0 , account = 0;
char dummy, resp, accno_input[25], name[25], icno[25],email [40], phone_number[25],acc_num[25],password[25],month[25], year[25];
account_num:
cout << " Enter your account number : ";
cin >> accno_input;
ifstream file("Membership.txt");
while (!file.eof()){
getline(file, line);
count++;
}
cout << accno_input;
int i = 0;
while(i <= count)
{
member.getline(name,25,'|');
member.getline(icno,25,'|');
member.getline(email,40,'|');
member.getline(phone_number,25, '|');
member.getline(acc_num,25, '|');
member.getline(password,25,'|' );
member.getline(month,25,'|' );
member.getline(year, 25);
cout << name << " ";
cout << icno << " ";
cout << acc_num << " ";
cout << accno_input;
if (acc_num == accno_input){
account = 1;
break;
}
i ++;
}
cout << account;
member.close();
if ( account != 1 ){
cout << endl;
cout << " Your account not found !!!"<< endl;
cout << " Please try again !!" << endl << endl;
cout << " PLEASE ENTER ANY KEY TO CONTINUE >>> ";
cin >> dummy;
goto account_num;
}
password1 = password;
cout << endl;
cout << " Enter your account password : ";
cin >> pass_input;
for (login_attempt = 1 ; login_attempt <= 2 ; login_attempt ++){
if (pass_input == password1){
cout << "Login Successful !!!";
break;
}
cout << endl;
cout << "Login Failed. Attempt " << login_attempt << " of 3" << endl;
cout << "Please re-enter Password: " ;
cin >> pass_input;
if (pass_input == password1){
cout << "Login Successful !!!";
break;
}
}
if ( login_attempt == 3){
cout << endl;
cout << "Login Failed. Attempt 3 of 3";
}
return accno_input;
}
There are so many things completely wrong in your program that I do recomend to you:
Delete and start from scratch.
There is no meaningful fix possible. There is even a goto. And you MUST stop using C-Style arrays with some agic dimension in C++. And C++ has many things to make your live easier. Simply use them.
Please find below a C++ solution.
You can copy and paste it and stay as you are, or, you take 3 hours and google all constructs and try to understand and learn and become a better programmer. Your choise.
#include <iostream>
#include <fstream>
#include <string>
#include <iomanip>
#include <vector>
#include <regex>
#include <iterator>
#include <algorithm>
const std::regex re{ R"(\|)" };
struct Member {
// Memeber data
std::string name{};
std::string icno{};
std::string email{};
std::string phoneNumber{};
std::string accountNumber{};
std::string password{};
int month{};
int year{};
// Extractor operator
friend std::istream& operator >> (std::istream& is, Member& m) {
// Readone complete line
if (std::string line{}; std::getline(is, line)) {
// Split it into parts
std::vector parts(std::sregex_token_iterator(line.begin(), line.end(), re, -1), {});
// assign parts to member data
if (parts.size() == 8) {
m.name = parts[0]; m.icno = parts[1]; m.email = parts[2]; m.phoneNumber = parts[3]; m.accountNumber = parts[4]; m.password = parts[5];
m.month = std::stoi(parts[6]); m.year = std::stoi(parts[7]);
}
}
return is;
}
};
// Filename for member data
const std::string fileName{ "r:\\Membership.txt" };
int main() {
// Open the data file and check, if it could be opened
if (std::ifstream fileStream{ fileName }; fileStream) {
// Read complete source file, parse it and get all data
std::vector memberData(std::istream_iterator<Member>(fileStream), {});
// We want the user to give 3 trials to enter valid data
constexpr unsigned int MaxTrials = 3u;
unsigned int numberOfTrials{};
// A valid input will stop the loop immediately
bool validInputgiven{};
// Now, try to get the correct input
while (not validInputgiven and numberOfTrials < MaxTrials) {
// Get an acoount number
std::cout << "\nEnter a account number: ";
std::string account{};
std::cin >> account;
// Check, if the account number is in the member data
if (std::count_if(memberData.begin(), memberData.end(), [&](const Member& m) { return m.accountNumber == account; }) > 0) {
// Account info wasOK. Get the password
std::cout << "\nEnter your password: ";
std::string password{};
std::cin >> password;
if (std::count_if(memberData.begin(), memberData.end(), [&](const Member& m) { return m.accountNumber == account and m.password == password; }) > 0) {
// Valid data found
validInputgiven = true;
std::cout << "\n\nEverything OK. Data validated.\n\n";
}
}
// Next try
++numberOfTrials;
if (not validInputgiven and numberOfTrials < MaxTrials) std::cout << "\nInvalid input. Please try again\n\n\n";
}
if (not validInputgiven ) std::cout << "\nToo many wrong tries. Aborting . . .\n\n\n";
}
else std::cerr << "\n\nError. Could not open source file '" << fileName << "'\n\n";
}

Accessing Variable values from another file c++

I am doing something that requires a password.
right now I am able to create files and store custom user input in that but I cant seem to find anywhere how to store a variable with the user created value, and make it so that the next time the program starts it will be able to read that file and understand the value.
#include "stdafx.h"
#include "string"
#include "iostream"
#include "fstream"
#include "windows.h"
using namespace std;
int main() {
string user;
string pass;
string entry;
std::ifstream f("test.txt");
if (f.fail()) {
std::ofstream outfile("test.txt");
cout << "Please make a username.\n";
cin >> user;
cout << "Please make a password.\n";
cin >> pass;
outfile << user << std::endl;
outfile << pass << std::endl;
outfile.close();
cout << "Please restart.\n";
int x = 3000;
Sleep(x);
}
else {
cout << "please enter username\n";
cin >> entry;
if (entry == user) {
cout << "Welcome";
int x = 3000;
Sleep(x);
}
else if (entry != user) {
cout << "Nope";
int x = 3000;
Sleep(x);
}
}
return 0;
}
You haven't added the necessary code to read the saved user name and password. In the else part of the function, add
f >> user;
f >> pass;
as the first two lines.
else {
// Read the user name and password from the file.
f >> user;
f >> pass;
cout << "please enter username\n";
cin >> entry;
if (entry == user) {
cout << "Welcome";
int x = 3000;
Sleep(x);
}
else if (entry != user) {
cout << "Nope";
int x = 3000;
Sleep(x);
}
}
You can use string::find function to search your string in a file after ifstream.
if (string1.find(string2) != std::string::npos)
{
std::cout << "found\n";
}
else
{
std::cout << "not found\n";
}

Password to a program

I've made an app that solves some computations with matrices, and I want to authenticate users in order to grant them access when the program starts.
I will show you what I've done already.
int main()
{
const string USERNAME = "claudiu";
const string PASSWORD = "123456";
string usr, pass;
cout << "Enter Username : ";
cin >> usr;
if(usr.length() < 4)
{
cout << "Username length must be atleast 4 characters long.";
}
else
{
cout << "Enter Password : ";
cin >> pass;
if(pass.length() < 6)
{
cout << "Password length must be atleast 6 characters long";
}
else
{
if(usr == USERNAME && pass == PASSWORD)
{
cout << "\n\nSuccessfully granted access" << endl;
}
else
{
cout << "Invalid login details" << endl;
}
}
}
This is how my code looks like. All I want to do is that when I enter a wrong username or a wrong password the program shows the message I wrote and then let me introduce another username and password and when I introduce them correctly, the program starts.
I would make a logged_in variable, then set it to true when the condition is passed and run the whole login process in a while loop:
#include <iostream>
#include <string>
using namespace std;
int main()
{
const string USERNAME = "claudiu";
const string PASSWORD = "123456";
string usr, pass;
bool logged_in = false;
while (!logged_in)
{
cout << "Enter Username : ";
cin >> usr;
if (usr.length() < 4)
{
cout << "Username length must be atleast 4 characters long.";
}
else
{
cout << "Enter Password : ";
cin >> pass;
if (pass.length() < 6)
{
cout << "Password length must be atleast 6 characters long";
}
else
{
if (usr == USERNAME && pass == PASSWORD)
{
cout << "\n\nSuccessfully granted access" << endl;
logged_in = true;
}
else
{
cout << "Invalid login details" << endl;
}
}
}
}
cout << "Passed login!\n";
}

How do I get my checkLength function to loop until the user enters in a password of more than 5 characters?

Okay so i am working a project where we are storing user input to create a username and password and storing it within a vector. My main issue is that everytime i use the checkLength function it still takes the user's password even though its less than 5 characters for example here's the output i am getting '
Enter your first name.
John
Enter your last name.
Stewart
Enter a password.
abc
Password is not 5 characters. please try again...
/**it displays the message but still
continues instead of making the user input a 5 character password**/
Enter your first name.
Example
Enter your last name.
exmaple
Enter a password.
prob
Password is not 5 characters. please try again...
Enter your first name.
0
Login data entered
JStewa, abc
Eexmap, prob
Press any key to continue . . .
How do I fix this or why is it looping even though the user only entered a three character password!
here is my code
//DISPLAY 8.9 Using a Vector
#include <iostream>
#include <vector>
#include <string>
using namespace std;
#include "c:\Users\barta\OneDrive\Documents\Visual Studio 2015\Projects\Project 7\Project 7\Validate.h"
int main( )
{
vector<string> data;
string firstName, lastName, login, userName, password;
Validate c;
firstName = "1";
cout << "Enter your first name.\n";
getline(cin, firstName);
while (firstName != "0")
{
cout << "Enter your last name.\n";
getline(cin, lastName);
do
{
cout << "Enter a password.\n";
getline(cin, password);
c.checkLength(password);
lastName = lastName.substr(0, 5);
userName = firstName.at(0) + lastName;
login = userName + ", " + password;
data.push_back(login);
} while (false);
cout << "Enter your first name.\n";
getline(cin, firstName);
}
cout << " Login data entered \n" << endl;
for (unsigned int i = 0; i < data.size(); i++)
{
cout << " " << data.at(i) << endl;
}
system("pause");
return 0;
}
Validate header file:
class Validate
{
public:
Validate(string);
Validate();
bool checkLength(string);
bool checkSpaces();
bool checkUpper();
private:
string password;
static const int LEN = 5;
};
Validate::Validate()
{
}
Validate::Validate(string pass)
{
pass = password;
}
bool Validate:: checkLength(string password)
{
if (password.length() < LEN)
{
cout << "Password is not 5 characters." << " please try again..." << endl;
return true;
}
else
{
return false;
}
}
loop on checking the length and do everything else outside the loop
bool badLength;
do
{
cout << "Enter a password.\n";
getline(cin, password);
badLength = checkLength(password);
} while (badLength);
lastName = lastName.substr(0, 5);
userName = firstName.at(0) + lastName;
login = userName + ", " + password;
data.push_back(login);

getting a string to work in password function

Hi apologies for my poor explanation I'm very new to this. I am currently working on a password function but I'm having problems. I have set the account name to string "john" and the account password to int 1111. The password works fine but the string is causing the error. When I change "const string name = "john"" into a random integer the code works fine.
I was hoping someone could spot where I'm going wrong?
bool login() {
const int password = 1111;
int passwordAttempt;
const string name = "john";
string nameAttempt;
int attempts = 0;
std::cout << "Please Enter Password:" << std::endl; //first attempt at account number & password
std::cin >> passwordAttempt;
std::cout << "Enter Name:"<< std::endl;
std::cin >> nameAttempt;
if (passwordAttempt == password && nameAttempt == name) {
return true;
}
else
while (passwordAttempt!=password || nameAttempt!=name) {
if(attempts++ ==2)//.. a loop for two more attempts
{
std::cout << "You have entered the wrong details three times. The application will be terminated now" << std::endl;
return false;
break;
}
std::cout<<"Incorrect password. Try again"<<std::endl;
std::cout<< "" <<std::endl;
std::cout << "Please Enter Password:" << std::endl;
std::cin >> passwordAttempt;
std::cout << "Enter Name:"<< std::endl;
std::cin >>nameAttempt;
}
}
using namespace std;
int main() {
bool loggedIn = login();
if (loggedIn){
cout << "Logged In" << endl;
}
else if (!loggedIn){
cout << "Not Logged" << endl;
}
system("pause");
return 0;
}
Add std:: to your string declarations (so you will have std::string).
After while loop there's end of function login without any value return. Add return true there. Also always build with warnings enabled!