Problem with password code! Help!

Hey I've been writing this bs program to reteach myself C++ and I can't seem to figure out how to assign an initial, changeable value to a private variable. I tried assigning it in the constructor, but it needs to be changeable and everytime I access it, since its in the constructor, it resets to the initial value that I set.

I'm trying to create a limit on the # of password attempts for this program and then display the # of attempts left, while also displaying the # of failures recorded. I had it working before I put it all into a class, but I cannot seem to figure out how to get it to work while they are private variables being accessed by public functions...

Here's my code so far:
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
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
#include <iostream>
#include <string>
#include "windows.h"

using namespace std;
string TryAgain;

class SecurityLog
{
public:
/*	SecurityLog()
	{
		ResetFails();
		ResetAttempts();    // Would be idea except for the fact that this resets the value to 3
	} */					// Each time it is called, defeating the purpose of the functions
	int GetFailCount() {
		return FailCount; }
	int GetAttemptsLeft() {
		return AttemptsLeft; }
	void AddFail() {
		FailCount++; }
	void SubAttempt() {
		AttemptsLeft--; }
	void ResetFails() {
		FailCount = 0; }
	void ResetAttempts() {
		AttemptsLeft=3; }
private:
int FailCount; // Needs to be initially set to 0, IDE wont let me set this here.
int AttemptsLeft; // Needs to be initially set to 3, ^          ^            ^
};
void Success();
void menu() // new menu using a case switch
{
	SecurityLog sl;
	int loop=1;
	int choice;

	system ("cls");

	while (loop==1)
	{
		system("CLS");
		cout << "[SYSTEM] Secret Menu\n"
			 << "1. Show the secret code\n"
			 << "2. View security log\n"
			 << "3. Go back\n"
			 << "4. Exit the program\n" 
			 << "Enter the # of the option to select it.\n"
			 << ">";
		cin >> choice;
		switch(choice)
		{
		case 1:
			cout << "[SYSTEM] The secret code is gopass\n\n";
			cout << "[SYSTEM] Command finished.\n\n";
			system ("pause");
			menu();

		case 2:
			printf("[SYSTEM] There have been %d failed logon attempts. \n", sl.GetFailCount());
			cout << "[SYSTEM] Command finished.\n\n";
			system ("Pause");
			menu();

		case 3:
			system ("cls");
			Success();

		case 4:
			if(choice=4)
			{
				cout << "[SYSTEM] The system has shut down. \n"
					 << "[SYSTEM] The program will now exit...";
				Sleep(1500);
				exit(0);
			}
		}
	}
}
class CalcFuncs { //only used by calc();
	public:
void calcadd()
{
	float a;
	float b;
	float sum;

	cout << "Enter a number:\n" << ">";
	cin >> a;
	cout << "Enter another number:\n" << ">";
	cin >> b;

	sum = a + b;

	//printf("\nThe answer is %d\n", sum);
	cout << "The answer is " << sum << endl;
	cout << "Press enter to go back to the calculator.";
	cin.get();
}
void calcsub()
{
	float a;
	float b;
	float sub;

	cout << "Enter the # to be subtracted from:\n" << ">";
	cin >> a;
	cout << "Enter the # to be subtracted:\n" << ">";
	cin >> b;

	sub = a - b;

	//printf("\nThe answer is %d\n", sub);
	cout << "The answer is " << sub << endl;
	cout << "Press enter to go back to the calculator.";
	cin.get();
}
void calcdiv()
{
	float a;
	float b;
	float div;

	cout << "Enter the # to be divided:\n" << ">";
	cin >> a;
	cout << "Enter the # to be divided by:\n" << ">";
	cin >> b;

	div = a / b;

	//print("\nThe answer is %d\n", div);
	cout << "The answer is " << div << endl;
	cout << "Press enter to go back to the calculator.";
	cin.get();
}
void calcmult()
{
	float a;
	float b;
	float mul;

	cout << "Enter the # to be multiplied:\n" << ">";
	cin >> a;
	cout << "Enter the # to be multiplied by:\n" << ">";
	cin >> b;

	mul = a * b;

	//printf("\nThe answer is %d\n", mul);
	cout << "The answer is " << mul << endl;
	cout << "Press enter to go back to the calculator.";
	cin.get();
}
}; // Only used by calc();
void calc(); // Calc prototype for "go back" option
void Authorize(); // Authorize prototype for logout function
void Success()
{
	SecurityLog sl;
	string choice;
	//system ("cls");
	cout << "[SYSTEM] Commands:\n" 
		 << "smenu	- Opens the secret menu\n" 
		 << "calc	- Opens the calculator\n"
		 << "cmd	- Enters the command prompt\n"
		 << "logout	- Logs out of the system\n"
		 << "exit	- Exits the program\n"
		 << ">";
	cin>>choice;
	if(choice == "smenu")
	{
		cout << "[SYSTEM] Entering the menu...\n";
		menu();
	}
	if(choice == "cmd")
	{
		cout << "[SYSTEM] Entering the command prompt...\n";
		Sleep(1500);
		system ("cls");
		system ("cmd");
	}
	if(choice == "calc")
	{
		cout << "[SYSTEM] Starting the calculator...\n";
		Sleep(1500);
		calc();
	}
	if(choice == "logout")
	{
		cout << "[SYSTEM] Resetting security log...\n";
		sl.ResetFails();
		sl.ResetAttempts();
		//FailCount=0;
		//AttemptsLeft=3;
		Sleep(500);
		cout << "[SYSTEM] Done.\n"
			 << "[SYSTEM] Logging out...\n";
		Sleep(1500);
		system ("cls");
		Authorize();
	}
	if(choice == "exit")
	{
		system ("cls");
		cout << "[SYSTEM] The system has been shut down. \n"
			 << "[SYSTEM] The program will now exit...";
		Sleep(1500);
		exit(0);
	}
	else
	{
		cout << "[SYSTEM] The command entered was not recognized.\n\n";
		system ("Pause");
		system ("CLS");
		Success();
	}
}
void Failure() // Here you can see I attempt to change the variables when the Failure(); function
               // is called...the idea would be to add one to the failures, subtract one from the attempts remaining
{
	SecurityLog sl;
	sl.SubAttempt();
	sl.AddFail();
	//AttemptsLeft--; Now a private variable - Func
	//FailCount++; Now a private variable - Func

	if(sl.GetFailCount() < 3)
	{
		system ("cls");
		cout<<"[SYSTEM] Wrong Password!\n";
		cout<<"[SYSTEM] You have " << sl.GetAttemptsLeft() << " attempts left.\n";
		cout<<"[SYSTEM] Do you want to try again? Type y for Yes and n for No to continue...\n";
		cin>>TryAgain;

		}
		else
		{
			cout << "[SYSTEM] You have entered the wrong password too many times!\n"
			 << "[SYSTEM] The system has shut down.\n"
			 << "[SYSTEM] The program will now exit...\n"
			 << sl.GetFailCount() << " Fails & " << sl.GetAttemptsLeft() << " Attempts left.";
			Sleep(3000);
			exit(0);
		}
}
int main()
{
	SecurityLog sl; // Removed alot of the code here to fit it into this forum post....lol, wasn't useful anyway.
	cout << "[SYSTEM] Authorizing...\n";
	Authorize();

	return 0;
}
void Authorize()
{
		string getinput;
	do
	{
		cout<<"[SYSTEM] Please enter the password:  ";
		cin>>getinput;

			if (getinput == "gopass")
			{
				system ("cls");
				cout << "[SYSTEM] You have gained entry to the system!\n"
					 << "[SYSTEM] What would you like to do now?\n\n";
				Success();
				//TryAgain = " ";
			}
			else
			{
				Failure(); // The wrong password is entered, calling the Failure(); function
			}                  // Ideally, this should add one to the failure count and subtract one
		}                          // from the attempts remaining, and then display them.
	while (TryAgain == "y");
	{
				cout<<"[SYSTEM] The system has shut down.\n"
					<<"[SYSTEM] The program will now exit...";
				Sleep(2000);
				exit(0);
	}
}
void calc()
{
	CalcFuncs cf; // creating a class object for ClassFuncs
	int choice1;
	int loop=1;
	while (loop==1)
	{
	system ("cls");
	cout << "Enter your choice of calculatory functions...\n"
		 << "1. Addition\n"
		 << "2. Subtraction\n"
		 << "3. Division\n"
		 << "4. Multiplication\n"
		 << "5. Go back\n" << ">";
	cin >> choice1;
	if (choice1==1)
	{
		cf.calcadd();
	}
	if (choice1==2)
	{
		cf.calcsub();
	}
	if (choice1==3)
	{
		cf.calcdiv();
	}
	if (choice1==4)
	{
		cf.calcmult();
	}
	if (choice1==5)
	{
		system ("cls");
		Success();
	}
	cin.get();
	}
	cin.get();
}



I wasn't kidding, its a BS program with absolutely no use... I'm simply writing it to reteach myself C++, like I said. But anyways, I'm just trying to get that FailCount variable set to 0 initially so that it can be properly added to, up to the maximum 3 that will trigger the program to exit, and the AttemptsLeft variable intially set to 3 so that it can be subtracted from and displayed. Anyone have any ideas on how I can do this? Advice on any other part of the code would also be greatly appreciated!

Thanks!
Last edited on
You can do it in the constructor.

1
2
3
SecurityLog::SecurityLog() : FailCount( 0 ), AttemptsLeft( 3 )
{
}


or define the constructor inline in the class definition.

SecurityLog() : FailCount( 0 ), AttemptsLeft( 3 ) {}
Last edited on
That wont reset it to 0 and 3 each time i use an object?

I tried setting them in the constructor like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Class SecurityLog
{
Public:

SecurityLog ()
{
FailCount = 0;
AttemptsLeft = 3;
}
....blabla

Private:
int FailCount;
int AttemptsLeft;
}


And it would reassign the values to 0 and 3 each time i used an object to access the functions in public. Ill give this a shot though thank you!
Last edited on
I've added it to my code as follows:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class SecurityLog
{
public:
SecurityLog::SecurityLog(): 
FailCount(0), AttemptsLeft(3) {}

/*	SecurityLog()
	{
		ResetFails();
		ResetAttempts();    // Would be ideal except for the fact that this resets the value to 3
	} */					// Each time it is called, defeating the purpose of the functions

	int GetFailCount() {
		return FailCount; }
.....


This works, but I'm having the same problem as before. Every time my program uses an object to access the functions in public, it resets the values to 0 and 3...which again, defeats the purpose of being able to subtract and add to those values:

Each failed login should decrease the AttemptsLeft from 3-2, 3-1, and then 3-0.
Each failed login should also inrease the FailCount from 0-1, 0-2, and then 0-3.
At 3 failures, the program exits.

A bit more help or other suggestions would be greatly appreciated. I had this code working before I attempted to make the FailCount and AttemptsLeft private variables, but because I'm not familiar with class and object oriented coding yet, I seem to be running into a bit of trouble here when working with constructors.

Thanks again.
Last edited on
bump, still seeking a solution to this.
If I got what you mean, each object SecurityLog sl is a different one in each function!
that means that each time the compiler finds that string a different SecurityLog is created.
Each of those are different object (for your computer that means that it's like me and you digiting the wrong pin for our debit card!).
Depending on what you need (i couldn't read the entire program), you might want to have those variables being static (then you have to initialize them with type className::varName = whatever, outside from the class)
In this case, if you have 200 different SecurityLog, they have (as total) 3 attempts. And if one fails also all the other 199 fail.
The other possibilities is that (and I think that's what you want) you pass a SecurityLog & sl to ALL your functions...
If I got this wrong, forgive me!
Last edited on
Perhaps I misunderstood what you are trying to do. Do you want to instantiate multiple SecurityLog objects and have them all access the same FailCount and AttemptsLeft variables? If so, just use the default constructor and make FailCount and AttemptsLeft static in the class definition.

1
2
3
private:
   static int FailCount;
   static int AttemptsLeft;


Now initialize these static members in the .cpp file.

1
2
int SecurityLog::FailCount = 0;
int SecurityLog::AttemptsLeft = 3;


All SecurityLog objects will now use the same FailCount and AttemptsLeft variables.
Last edited on
Well the only places I utilize the functions are here:
(This is in void Success() )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
	if(choice == "logout")
	{
		cout << "[SYSTEM] Resetting security log...\n";
		sl.ResetFails();
		sl.ResetAttempts();
		//FailCount=0;
		//AttemptsLeft=3;
		Sleep(500);
		cout << "[SYSTEM] Done.\n"
			 << "[SYSTEM] Logging out...\n";
		Sleep(1500);
		system ("cls");
		Authorize();
	}


and here:

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
void Failure() // Here you can see I attempt to change the variables when the Failure(); function
               // is called...the idea would be to add one to the failures, subtract one from the attempts remaining
{
	SecurityLog sl;
	sl.SubAttempt();
	sl.AddFail();
	//AttemptsLeft--; Now a private variable - Func
	//FailCount++; Now a private variable - Func

	if(sl.GetFailCount() < 3)
	{
		system ("cls");
		cout<<"[SYSTEM] Wrong Password!\n";
		cout<<"[SYSTEM] You have " << sl.GetAttemptsLeft() << " attempts left.\n";
		cout<<"[SYSTEM] Do you want to try again? Type y for Yes and n for No to continue...\n";
		cin>>TryAgain;

		}
		else
		{
			cout << "[SYSTEM] You have entered the wrong password too many times!\n"
			 << "[SYSTEM] The system has shut down.\n"
			 << "[SYSTEM] The program will now exit...\n"
			 << sl.GetFailCount() << " Fails & " << sl.GetAttemptsLeft() << " Attempts left.";
			Sleep(3000);
			exit(0);
		}


The idea is that it needs to be a globally accessible variable that stays consistent between both functions. If one functions changes it, it should be changed for the other function.

I'm probably doing this wrong. If you could clarify how to accomplish this I would be greatly appreciative... again, i'm not very familiar with how classes/objects work yet, but I'm doing this to try and learn.
Last edited on
Alrededor wrote:
Perhaps I misunderstood what you are trying to do. Do you want to instantiate multiple SecurityLog objects and have them all access the same FailCount and AttemptsLeft variables? If so, just use the default constructor and make FailCount and AttemptsLeft static in the class definition.

1
2
3
private:
   static int FailCount;
   static int AttemptsLeft;


Now initialize these static members in the .cpp file.

1
2
int SecurityLog::FailCount = 0;
int SecurityLog::AttemptsLeft = 3;



All SecurityLog objects will now use the same FailCount and AttemptsLeft variables.


I have my entire program in the same .cpp file, so when you say in the .cpp file you mean anywhere in the main function?

EDIT: scratch that, i tried a couple things until i figured out I could just add it right after the class definition

Thanks a bunch, this works perfectly.

What is the difference between a normal int declaration and a static int declaration?
Last edited on
I have my entire program in the same .cpp file, so when you say in the .cpp file you mean anywhere in the main function?


It is common to put a class definition in a header file and then the class implementation in the a code file. The code file includes the header file.

SecurityLog.h

1
2
3
4
5
6
7
// any includes needed by the class definition

class SecurityLog
{
.
.
};


SecurityLog.cpp

1
2
3
#include "SecurityLog.h"

// implementation of the class member functions. 


Some compiliers use extensions other than .cpp for code files.

What is the difference between a normal int declaration and a static int declaration?


For normal class member variables, whether public or private, each instantiated object has its own member variables, as you found above. When the member variables are declared as static the variables are unique and separate from any instantiated class, though they can still be accessed through any particular class object. All instantiated objects share the same static variables. This is why static variables cannot be initialized in the constructor, but need to be initialized separately. It is even possible to access the public static members of a class without actually instantiating any class objects in the program. This is done through the class scope resolution operator. If in your SecurityLog class FailCount had been public, you could write:

1
2
3
4
5
int main()
{
   std::cout << SecurityLog::FailCount << std::endl;
   return 0;
}


This would output 3 even though no SecurityLog objects are instantiated in the program.

By the way, the above is not an argument for making FailCount public but just to illustrate using the scope resolution operator to access public static member variables.

There is one exception to the rule that static member variables must be initialized outside the class definition. Static member variables of const integral type can be initialized inside the class definition.
For example, if FailCount were const you could write in the class definition:

1
2
private:
   const static int FailCount = 3;



I was aware that could be done I just didn't really find it necessary since I only have 2 classes in my program so far, however I should probably do that since I plan to expand this as I become more familiar with the language. Is there a benefit to doing this besides making the program more organized and easier to edit?

thanks a lot for the info so far! Everything seems to be working, now to find out what else i can make :P
Last edited on
Is there a benefit to doing this besides making the program more organized and easier to edit?


Reusing the class in another program. Adding the two files SecurityLog.h and SecurityLog.cpp to a new project together with the line #include "SecurityLog.h" would be simpler than copying and pasting the code. In addition, if you discover a bug in the class code or decide to make an improvement to the class and modify the code, with the class in a separate file you only need to modify the code in one place and then recompile the projects that use the class. With Copy and Paste you would have to find and modify the code in each project where you have copied and pasted the code. In a simple program where code reuse will not be an issue it doesn't really matter.
Topic archived. No new replies allowed.