Program repeats a statement when it shouldn't

I'm still extremely new to c++, and I'm having the most annoying trouble with this program I just wrote.
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
#include <iostream>
#include <stdlib.h>
#include <string>

int correctPassword(); 

using namespace std;

int main()
{
  int nPasswordAttempts = 0;
  
  do										// do while loop with a counter to limit failed password attempts
  {
  cout << "Enter the password to continue or 0 to quit: ";
  int password;
  cin >> password;
    
  if (password==4844509)
    correctPassword();
	
    else if (password == 0) 							//allows the user to quit with a command
      return 0;

    else
    {
      cout << "Invalid password, please try again.\n";
      ++nPasswordAttempts;							//counter for the password Attempts
    }
  }
  while(nPasswordAttempts < 3);							//end of do while loop. (limit of 3 password attempts)
  cout << "Failed attempts limit exceeded: exiting...\n";
  return 0;
}



/* IF THE PASSWORD IS CORRECT */




int correctPassword()
{
  cout << "You knew the password; your reward is this message!" << endl;

  loop:									//loop created to allow for error handling incase invalid character is entered
  cout << "Press 1 to return, or 0 to quit: ";
  int nChoice;

  cin >> nChoice;
      
  if (nChoice == 1)
  {
    cout << string(50, '\n'); 
    main(); 
  }
      
  else if (nChoice == 0)
  { 
    cout << string(50, '\n'); 
    return 0;
  }              

  else 
  {
    cout << "Error: invalid choice, please try again\n"; 
    goto loop;
  }
}


It's fairly self explanitory. Enter the password to get a message, enter 0 to quit, and any other character gives you an error.

Once you've received the message, hit 1 and it clears the screen and returns to the first message, hit 0 and it quits the program, any other key gives you an error.

Here's the problem, once I've entered the password and received the message, then hit zero to quit, rather than quitting, it returns to the main function!, then I hit zero there, and it (sometimes) displays the first message again. So I always have to hit zero at least twice in order to exit once receiving the message, and sometimes I have to hit it 3 times. What have i done wrong?
Last edited on
1) don't use goto. If you want to loop, use a loop (like a while loop)
2) never call main(). Ever. Never ever ever.
3) return does not quit the program like you seem to think. It simply exits the function. The program resumes from wherever you were before the function call (so if main calls correctpassword, then when correctpassword returns, the program will return to main)
Thanks for the response.

I fixed the correctPassword() function with a while loop instead of goto. However, I still have a couple of questions.

What do I use instead of calling main()?

and thanks for the information about return, but what should I use to quit the program instead?

(I'm using a g++ compiler on linux, so I can't use anything that requires a windows header file.)


edit: nvm, I think I figured how what to do instead of calling main(). is it return 1;? (I still don't know what to use instead of return 0;
Last edited on
(On a side note, what is the reason for never calling main?)
Last edited on
Main is a function and an int for historic purposes. if you need to call main in a function, take the code you want to execute in main and place it in its own function.

Your 'main' function is like home base. in C++, you generally use main to read your input/output and print things out (although you can print in functions too).

A good practice to get into when you find yourself writing a lot of complicated code in your main function is to section off that piece into a function and just call it in main. It just nicely wraps up pieces of your program for others to read.

If all your other functions work and pass arguments correctly, all you have to do is call them in main. It's mainly to help organize chunks of code and avoid unnecessary repetition.
Last edited on
Thanks for the info.

So then do I use return 1; Instead of calling main?

and what do I use in place of return 0; to quit the program?
Main doesn't have to return anything actually: this is mainly done out of habit for historic purposes as well. (Depending on the compiler I believe)

Your program doesn't really need a function, but if you are practicing writing functions then instead of "calling" main, just write end. This should exit the program.
Also, instead of writing:

cout << string(50, '\n');

You can use a built in function of the <iostream> library to insert a line break.

cout << endl;
Yeah, I know I can use endl;, but I'm trying to make it look like it's clearing the screen.

I don't think you entirely understood my question.

Disch said that I should never call main, so I'm trying to figure out an alternative to it, which, using return 1; seems to work properly.

My other delima is how to end the program. I tried putting end; just now, but the compiler complains that it was not declared.

(also, I know that I could make it all within main(), but It seems more neat and easy to read this way, and I am still a newb so it can't hurt to practice functions.
Last edited on
I do get what you're saying, but think about your program for a second.

You are doing everything WHILE the number of password attempts is less than 3. What if the user inputs the correct password on the first try? Password attempts is still going to be 0.
yes, I know that. (I guess I should change the name of the variable to failed password attempts. Since that was the whole idea, is that if you input the wrong password in 3 times, the program exits.)

I think I'm starting to get this, so let me revise my question once more.

What is the correct statement to end the program from line 62 instead of return 0; ?
Last edited on
I thought it was end, but you can alternatively do a quick Google search for that.

Have a look at this code. In your case, I think functions over-complicate things.

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
#include <iostream>
#include <stdlib.h>
#include <string>
using namespace std;

int main()
{
	int nPasswordAttempts = 0;
	int password;
	int keyPress;
	
	while(true) //While the user has not entered the correct password or gone over the limit of attempts
	{
		cout << "Enter the password to continue or 0 to quit: ";
		cin >> password;
		if(password == 4844509 || nPasswordAttempts == 3) break; //If those conditions have been satisfied
		cout << "Invalid password, please try again.\n";
		++nPasswordAttempts;
	}
 
	//Decision time:
	if(password == 4844509)
	{
		cout << "You knew the password; your reward is this message!" << endl;
		cout << "Press 1 to return, or 0 to quit: ";
		cin >> keyPress;
		
		//Fill in the rest
	}
	else if(nPasswordAttempts == 3)
	{
		cout << "Failed attempts limit exceeded: exiting...\n";
	}						
}
okay, thanks, I'll try that out. But at some point, I'm going to have to use a function, and I would like to know how to properly exit from it.

Also, with this code, how to I return to the beginning of the function once the correct password has been entered? Since I've been told I shouldn't be calling main().
You can end the program with exit(0); but 99.9999999% of the time it's the wrong thing to do.

The larger problem here is that your overall structure is all wrong. You're using functions incorrectly -- as if they were gotos.


Functions have 2 major purposes:

1) They break code up into smaller tasks so that it's easier to manage
2) They allow for code reuse since you can call the same function from different parts of the program.


Since this program is pretty small, you're only really concerned with point #1: splitting the overall job into smaller tasks.

The problem is "correctPassword" isn't a task. It's more like a label name (again, you seem to be thinking of it as if it's a goto)

Examples:
void GetUserInput(); is a good function
void UserPressedA(); is a bad function
bool IsGreaterThan3(int v); is a good function
bool Section3(int v); is a bad function


To help change your mindset, names of functions should be verbs. That is, what the function does and/or returns can be summed up in the function name.


zachwulf's point of functions overcomplicating things in this case is probably true.


Also...

how to I return to the beginning of the function once the correct password has been entered?


If you want code to repeat (aka "loop"), put that code in a loop.
Last edited on
Okay, I think I understand now. So I wont use a function in this program, but if I ever am in a function, I shouldn't quit from it, instead it should return to the main() function and quit from there with return 0;
Topic archived. No new replies allowed.