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".
Related
I've created a simple logging in/ signing up program that reads and writes from files. It asks to log in or sign up and if you choose sign up, it writes to a seperate text file with the credentials (username and password). If you choose log in, it SHOULD compare your credentials with all the credentials in the file and say if it is a valid account.
Here is the code (shockingly long I know; I'm only 13 so I kinda suck at this):
#include <iostream>
#include <vector>
#include <fstream>
using namespace std;
// Function that gets username and password from the user
vector<string> askForCredentials(){
string username, password;
cout << "Please enter a username: ";
getline(cin, username);
// Repeatedly asks the question until the input has no spaces
while(username.find(" ") != string::npos){
cout << "No spaces in the username!" << endl;
cout << "Please enter a username: ";
getline(cin, username);
}
//Again
cout << "Please enter a password: ";
getline(cin, password);
while(password.find(" ") != string::npos){
cout << "No spaces in the password!" << endl;
cout << "Please enter a password: ";
getline(cin, password);
}
return {username, password};
}
int main() {
//Declares variable for user input
string request;
cout << "Would you like to log in or sign up? ";
getline(cin, request);
//While the input is not log in or sign up it repeats the question
while(request != "log in" && request != "sign up"){
cout << "That is not a valid answer. Would you like to log in or sign up? ";
getline(cin, request);
}
//If the user wants to sign up...
if(request == "sign up"){
//Creates a vector calling the askForCredentials function which asks user for username and password
vector<string> credentials = askForCredentials();
//Opens accounts text file in append mode
ofstream accounts("current_accounts.txt", ios::app);
//If the file opens than say account created successfully, otherwise say couldn't make account
if(!accounts.is_open()){
cerr << "Couldn't create account" << endl;
return 0;
} else{
cout << "Account created successfully!" << endl;
}
//Appends username and password seperated by a space in the accounts file
accounts << credentials[0] << " " << credentials[1] << " " << endl;
accounts.close();
}
//If the user requests to log in...
if(request == "log in"){
//Creates vector with user input and says if file opens successfully or not
vector<string> credentials = askForCredentials();
ifstream accounts;
accounts.open("current_accounts.txt");
if(!accounts.is_open()){
cerr << "Couldn't log in" << endl;
return 0;
}
// Need help here
return 0;
}
}
My problem lies in the log in part. I basically need to iterate through every line of credentials in the current_accounts file and compare it to the entered credentials. If anyone could help me out on this it would be greatly appreciated! Also I can respond if you need more information.
Oh and also I would appreciate if you tell me how I could optimize but keep it readable.
You can add the follwoing statement to your software:
if (!accounts.is_open()) {
cerr << "Couldn't log in" << endl;
return 0;
}
else {
// Here we will store the status. Did we find the username and password or not
bool found = false;
// Temporary storage for username and password read from file
std::string userName;
std::string passWord;
// In a loop, read all usernames and password
while ((accounts >> userName >> passWord) and not found) {
// Check, if the data is present
if ((credentials[0] == userName) and (credentials[1] == passWord)) {
// If yes, indicate that and stop the loop
found = true;
}
}
// Show result
if (found) std::cout << "\nLogin successfull\n\n";
}
Here we read all data from the file in a loop and compare it with the entered data.
The extractor operator >> will skip all white spaces, so reading is easy.
This will work, because you did not allow for spaces in username and password.
You could also read a complete line in a loop using std::getline, put the line into a std::istringstream and extract from there. This is normally the recommended approach, but in your case not necessary.
And your code is quite good. Especially the many comments are really good.
Design wise I would recommend to store the username and password in a struct and not in a vector of strings.
I have been trying to make a login interface where the user registers first into the system with some data like username, password, address, and email while using "-" as a delim between the data after storing them in a text file as below.
user1-pass1-user1#gmail.com-1 New York city
user2-pass2-user2#gmail.com-2 New York city
then using the code below I try to look for the username and password within the text but it only can extract the first line but not the second
void login()
{
string User, Pass, ConfirmUser, ConfirmPass;
cout << "Please Enter Your Name And Password to Login:\n";
<< "Username: ";
getline(cin, User);
cout << "Password: ";
getline(cin, Pass);
ifstream input("database.txt");
while (input) {
getline(input, u, '-');
getline(input, p, '-');
if (u == user && p == pass) {
authenticated = true;
system("cls");
}
input.close();
}
if (authenticated) {
cout << "\nHello " << user << "\nLogin Sucsses!";
cin.get();
cin.get();
}
else {
cout << "\nLogin Failed!\nPlease Check your Username and Password Again!";
main();
}
}
What do I need to do to get the code to check not only the first line of text but to check all of the text file as I will be adding more users?
Inside your while (input) loop, you have an input.close().
So, naturally, no input will be accepted after the first iteration.
Perhaps this sort of mistake would be easier to spot, if you used consistent/sensible indentation.
I haven't used fstreams much, so I'm a bit lost. I created a text file that has a list of random words that I wanted to use as a list of usernames and passwords for my program.
I want my program to check if the user exists (first string in the line), then check if the second word after it "matches".
So far I have this:
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int main()
{
ifstream inFile;
inFile.open("userData.txt");
// Check for error
if (inFile.fail()) {
cerr << "error opening file" << endl;
exit(1);
}
string user, pass;
int Count = 0;
// Read file till you reach the end and check for matchs
while (!inFile.eof()) {
inFile >> user >> pass;
if (user == "Banana", "Apple") {
Count++;
}
cout << Count << " users found!" << endl;
}
}
My text file contains:
Banana Apple /n
Carrot Strawberry /n
Chocolate Cake /n
Cheese Pie /n
I get my code is not good right now, but I don't really know what I'm doing.
Read below:
while (!inFile.eof()) {
inFile >> user >> pass;
if (user == "Banana", "Apple") {
Count++; // No point in doing so because this only happens once
}
cout << Count << " users found!" << endl;
}
Use while (inFile >> user >> pass){ instead of while (!inFile.eof()){. Why?
Try this instead:
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int main()
{
ifstream inFile;
inFile.open("userData.txt");
// Check for error
if (inFile.fail()) {
cerr << "error opening file" << endl;
exit(1);
}
string user, pass;
int Count = 0;
// Read file till you reach the end and check for matchs
while (inFile >> user >> pass) {
if (user == "Banana" && pass == "Apple") {
cout <<"user found!" << endl;
}
}
}
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.
I am trying to create a very simple program that writes to a file, but can't understand why it won't let me write to a file if I put it within an if statement! Here's the code:
#include "stdafx.h"
#include <iostream>
#include <fstream>
#include <string>
#include <stdlib.h>
using namespace std;
void readFile();
int main()
{
string line;
string today;
string readOrWrite;
cout << "Do you want to write to a file or read a file? " << endl;
cout << "Type \"write\" or \"read\" ";
cin >> readOrWrite;
if (readOrWrite == "read")
{
readFile();
}
else if (readOrWrite == "write")
{
cout << "How are you today? " << endl;
getline(cin, today);
ofstream myJournal;
myJournal.open("Journal.txt", ios::app);
myJournal << today << " ";
myJournal.close();
}
else
{
return 0;
}
return 0;
}
void readFile()
{
ifstream myJournal;
myJournal.open("Journal.txt");
string line;
if (myJournal.is_open())
{
while (getline(myJournal, line))
{
cout << line << endl;
}
myJournal.close();
}
else
{
cerr << "Error opening file ";
exit(1);
}
}
When I move it out of the if statement, it works smoothly and is able to write to the file, but when I place it inside, it opens the program, asks me the "Do you want to write to a file or read a file? ", I type "write", then it says "How are you today? " and then ends the program, printing "Press any key to continue...". Any help?
it says "How are you today? " and then ends the program, printing "Press any key to continue...". Any help?
std::istream::ignore should help in that case you are encountering.
cout << "How are you today? " << endl;
cin.ignore(10, '\n'); // Inserted
getline(cin, today);
Why do we need that in between?
It takes out 10 characters, which is enough amount of length, from the buffer and stops if it encounters a newline, which is '\n'. (Remember that you press the key 'enter' after typing "wrtie")
By doing so you can move on to the next new line, preventing std::cin from any parse failure.
More info : http://www.cplusplus.com/reference/istream/istream/ignore/