Login systems for multiple users

Hi everyone. I'm a c++ beginners and trying to make a simple login system for multiple users. New users can register for an account and login into the system. For my problem is about my programming system only can read the first username and password (in the first line). How to write out a command for the system to read the second user and password () second line) and third and so on... The user file will be like:

User1 Password1
User2 Password2
User3 Password3

Hope anyone here can help me. Use vector? or any other technique. Thanks a lot!


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
#include <iostream>
#include <fstream>
#include <string.h>
#include <iomanip>
using namespace std;

void login();
void registr();
void forgot();



int main(){
	
	int choice;
	cout <<"----------LOGIN----------\n";
	cout<< "1. Login\n"<< endl;
	cout << "2. Register\n" << endl;
	cout << "3. Forgot \n"<< endl;
	cout << " Enter your chioce: ";
	cin >> choice;
	
	switch(choice){
		
		case 1:
			login();
			break;
			main();
		case 2:
			registr();
			break;
			main();

		default :
			cout << "Unknown choice, pls enter your choice again."<<endl;
			
			return main();
		
	}
	
}

void registr(){
	
	string regUsername,regPassword;
	system("cls");
	cout<< "\n-----Register section-----"<<endl;
	cout << "Enter your username: ";
	cin >> regUsername;
	cout<< "\nEnter yout password: ";
	cin >> regPassword;
	
	ofstream reg("User.txt", ios::app);
	reg << regUsername<< setw(15) << regPassword<< endl;
	if (!reg.is_open()){
		cout<< "Error in opening file.";
	}else {
		system("cls");
		cout<< "Account created succesfully";
		main();
	}
	
}

void login(){
	int exist,enter;
	string logUsername, logPassword,logU,logP;
	system("cls");
	cout << "----- Login Section-----"<<endl;
	cout<< "Enter your username: ";
	cin >> logUsername;
	cout << "\nEnter your password: ";
	cin >> logPassword;
	
	ifstream log("User.txt");
	
	while (log >> logU >> logP ){
		if (logUsername == logU && logPassword == logP){
			cout<< "Welcome back "<< logUsername << " !"<<endl;
			exist = 1;
			break;
		}
		else if (logUsername == logU && logPassword != logP){
			
			cout << "Wrong password"<< endl;
			cout << "Please go back to main menu";
			exist = 0;
			break;
			
		}
		
		else{
			cout << "Wrong Username and password. Please try again."<< endl;
			cout << "Please go back to main menu.";
			exist = 0;
			break;
			
		}
	}
	log.close();
	

	
}
You break out from loop in the first iteration. That is why it reads only one entry.

You can't say that username is wrong before you have tested all names in the file.
Pseudo:
1
2
3
4
5
6
7
8
9
while ( log >> logU >> logP ) {
  if ( valid user ) {
    if ( valid password ) {
    } else {
    }
    break;
  }
}
// wrong user 



PS. What if you create "John", but the file does already contain at least one "John"?
Last edited on
Lines 28, 32: You will never reach these statements.

Lines 28, 32, 37, 60: You're handling repetition by use of recursion. You really should be using loops. There are a couple of reasons why recursion is a poor choice. 1) When you return from a nested main, you don't know why you returned, leading to incorrect program flow. 2) In theory, you can overflow the program's stack if you recurse enough times.

edit: Thanks jlb Didn't realize recursively calling main() was not allowed.

Last edited on
Also realize that recursively calling main() is not allowed in a C++ program.


Your switch() clauses probably need some break statements to prevent "fall through".

@keskiverto
Thanks for your suggetion and I have corrected the loop with my own idea and it is going well:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
	while (log >> logU >> logP ){
		if (logUsername == logU && logPassword == logP){
			exist = 1;
			if (exist == 1){
				break;
			}
			
		else{
			
			exist = 0;
		
			
		}
	}

Or any suggestion to make it more better/any problem? Btw, for the "same username" problem, I think I might need to build a checking system too to avoid same username. Is it what you mean?
Last edited on
@AbstractionAnon @jlb
Thanks for your correction! I will change my recursion into loop instead. I didnt't realize it will cause the problem(overflow).

@jlb what do you mean by "fall through"?
switches have fall through, which is a bug when you do not mean to do it, and powerful if you do mean to do it.
here is an example of it being useful:

cin >> ch;
switch(ch) //did the user want yes, no, or input junk?
{
case 'y':
case 'Y':
user_yes(); //this happens on both upper and lower case y because fall through (no break on the case)
break;
case 'n':
case 'N':
user_no();
break;
default: user_idiot();
}

it is bad if you had like
case 'y':
user_yes();
//break should go here, but it is missing
case 'n':
user_no(); //hey, this happens when they type y?! Oops: forgot the break statement!
Last edited on
Topic archived. No new replies allowed.