Returning to main() in c++ - c++

I just got into c++ and I'm just experimenting. I want to make a simple program which takes users input and calls one of 2 functions, then the function will print a line and ask the user if they want to go again. The issue is c++, for some reason, does not allow me to call main by simple saying main();
Is there any way to call the main function from another function? I am looking for the simplest solution there is, but I can't find anything :/
Here's the code:
#include <iostream>
#include <string>
using namespace std;
int do_math() {
cout << "Math" << endl;
string user;
cout << "would you like to go again? (y or n): " << endl;
cin >> user;
if (user == "y") {
main();
}
else if (user == "n") {
cout << "Okay, bye!";
exit(0);
}
return 0;
}
int do_eng(){
cout << "Eng";
string user;
cout << "would you like to go again? (y or n): " << endl;
cin >> user;
if (user == "y") {
main();
}
else if (user == "n") {
cout << "Okay, bye!";
exit(0);
}
return 0;
}
int main() {
string user;
cout << "Would you like to do math or end?:";
cin >> user;
if (user == "math") {
do_math();
}
else if (user == "end") {
do_eng();
}
return 0;
}

The issue is c++, for some reason, does not allow me to call main by
simple saying main(); Is there any way to call the main function from
another function? I am looking for the simplest solution there is, but
I can't find anything :/
No, you don't want to call main from any of your code.
Not that you should want to do this ... but the simplest solution is to provide a callable function, and get into it in the simplest way from main.
Perhaps:
int myMain()
{
string user;
cout << "Would you like to do math or end?:";
cin >> user;
if (user == "math") {
do_math();
}
else if (user == "end") {
do_eng();
}
return 0;
}
int main(int, const char**)
{
return myMain();
}
Lesson 1 - try to add another level of indirection (i.e. myMain()) does not have the restrictions of main()
Lesson 2 - learn something about recursion ... it seems you probably want to avoid it, here. (i.e. if you always invoke myMain(), how does your program ever terminate?
Lesson 3 - On my system, if the program terminates, I can up-arrow and launch it trivially. Terminal shells do this stuff for you. Perhaps this would be a better approach ... to always terminate unless the user selects one of the action choices (math, burp, etc.)
Lesson 4 - research other programs and how their user interface works. Find a model you like.
Note - I suppose, for your code to call myMain() again, you will need to 'forward declare' the function.

No, the standard specifically disallows calling main() from program code. What you want is to have a loop in main :
int main()
{
bool bContinue;
do
{
/* do something */
std::cout << "Do you want to go again?";
cin >> bContinue;
} while(bContinue);
}

Related

Prevent infinite recursion in c++

So, I'm triying to learn c++ (coming from python), and I wanted to make a program just to see if i could do it with what i've learned, here's the code
#include <iostream>
using namespace std;
int response(string i) {
if (i == "yes" or i == "Yes") {
cout << "\nHello, sad, I'm dad\n";
return(0);
}
else if (i == "no" or i == "No") {
cout << "Good for you pal\n";
return(0);
}
else {
cout << "Answer properly you overgrown flatworm\n";
response(i);
};
};
int main() {
string i;
cout << "Are you sad?";
cin >> i;
response(i);
};
Pretty simple huh? No. For some reason, yes and no answers work fine, but when I try something different I get insulted infinitely and the program crashes from exceeding it's memory limit. How do I solve this?
(English is not my native language, so feel free to correct any ortography mistakes)
At no point do you request further input. For bad input 'i', the response routine prints out an insult, and then calls itself with exactly the same string.
The response routine prints out an insult, and then calls itself with exactly the same string.
The response routine prints out an insult, and then calls itself with exactly the same string.
…
You need to allow the user to enter a new string, and then (if you want to use recursion) make the recursive call to validate the new input.
But as mentioned in the comment, this is not really a problem that needs a recursive solution.
This can be solved by eliminating recursion ad it involves moving the input routine inside of a function that's more self-contained:
int getResponse(string i) {
for(;;) {
string i;
cout << "Are you sad?";
cin >> i;
if (i == "yes" or i == "Yes") {
cout << "\nHello, sad, I'm dad\n";
return(0);
}
else if (i == "no" or i == "No") {
cout << "Good for you pal\n";
return(0);
}
else {
cout << "Answer properly you overgrown flatworm\n";
}
}
}
You have 2 issues:
In the else case, you are not asking for new user input.
You need to return the result of calling response(i), otherwise the code invokes undefined behavior.
else {
cout << "Answer properly you overgrown flatworm\n";
cin >> i;
return response(i);
};
Alternatively, since you never use the return value from response, you can just remove all the return statements, and make it a void function.
If you insist on using recursion then move the input and the check in the same function response() - that function doesn't need to return int at all. In main you can just call response().
void response()
{
string i;
cout << "Are you sad?";
cin >> i;
if (i == "yes" or i == "Yes")
{
cout << "\nHello, sad, I'm dad\n";
}
else if (i == "no" or i == "No")
{
cout << "Good for you pal\n";
return;
}
else
{
cout << "Answer properly you overgrown flatworm\n";
response();
}
}
int main()
{
response();
}

Big problem with classes , and returning from void function c++

so that's my first time learning a language , and I was really excited to play with classes, i do have one major problem which i cant seem to understand ;
im building a bank menu . its a class ofcourse, and i have a different class of clients which is basicly an array in my bank.
so my menu function inside the bank looks like that :
void menu (){
manager();
int n,m;
cout << "welcome to our bank managment system. \n";
cout << "please choose one of the following options : \n";
cout << "1-add a new client\n";
cout << "2-remove a leaving client\n";
cout << "3-bank statistics\n";
cout << "4-if you are a costumer\n";
cout << "5-exit\n";
cin >> n ;
if()
if()
if()
if()
if()
note that my return function is been summoned a lot inside
i have a return function to go back to the menu :
void returnfunction (){
int back = 0;
cout << "\n0-back to menu \n press a diffrent number back to exit :)\n";
cin >> back ;
if (back==0){
return menu();
}
if (back!=0){
cout << "thank you for using our program ! ";
return ;
}
it is working perfect until i play with it to much , and then hit 5 to exit (that's my option for n==5)
i must emphasize that when im hitting 5 only after few simple actions its working fine...
how can i fix that return function ?
ofcourse my main looks like that :
int main()
{
srand (time(NULL));
Bank b ;
b.menu();
}
appricate all of your wisom , thanks a lot
Your function:
void returnfunction ()
is declared to return nothing (void) but you:
return menu();
do return something, that's very unclear (even though menu() returns void too)
If you want to call menu() and then return write:
menu();
return;
There are a couple problems with this code, and honestly it wouldn't compile in other imperative OO languages. But this is c++ where the rules don't matter. Aside: If you don't have a strong reason to be using C++, learn Rust first. I promise you'll thank me later.
Paul has the right of it. The compiler should error out at that statement:
return menu();
However the equivalent is perfectly legal:
menu();
return;
But this still will cause problems in theory (but maybe not in practice) because your function is almost, but not, a candidate for tail recursion optimisation. More here Which, if any, C++ compilers do tail-recursion optimization?
This becomes a problem when users return to the menu many times, it depletes your programs memory, eventually leading to a stack overflow fault. The common pattern you'll find in most every GUI / Graphics library is that of a main-loop. Something like:
int main() {
bool exit = false
while(!exit) {
int action = menu()
switch(action) {
case EXIT_SELECTION: exit = true; break;
case SHOW_STATISTICS: printStats(); break;
}
}
}
Each time you call a function, your program has to use more memory to keep track of everything related to that function call. Ordinarily this memory is released once a function ends, but because your menu function calls another function that calls your menu function that calls another function... and on and on, you will eventually run out of memory from all of the function calls since these functions cannot terminate until the functions they call terminates -- and thus your program will crash. The solution is to use a while loop and check the user's input for an exit code as a previous responder mentioned. It can look something like:
`void menu() {
char choice= '\0';
while(choice!= 3) {
std::cout << "Welcome to the menu!";
std::cout << "\t Option 1 \n";
std::cout << "\t Option 2 \n";
std::cout << "\t Option 3 \n";
std::cout << "Your option: ";
std::cin >> choice;
if(choice == 1) { /*do something*/ }
else if(choice == 2) { /*do something else*/ }
else if(choice == 3) { /*print a message and exit*/ }
else { /*bad choice -- try again*/ }
} //end while-loop
} //end menu()`
Also, notice that your functions' return types are void, which, by definition, cannot have any sort of return. C++ will allow you to say return; inside of a void function, but it is merely a way to escape the function right then and there and is not really intended to do anything more than that. Using return in any other way when working with void functions is confusing and runs a risk of causing big issues.

Program does nothing when run

This program is a very simple one, a guessing game, however the issue is that when I compile it, it displays no errors. When I run it, it does nothing. I have tried fixing it, in that I moved the code within the guess() function back into main, and that works, printing "Enter a number between 0 & 100: ". Then when you do enter a number, it freezes, and this is probably caused by the lack of stop condition for the recursion. As I am not returning integers, as main has to, I reverted back to using the guess() function, and I have no idea why it doesn't work.
#include <iostream>
#include <cstdlib>
#include <string>
int computer = rand() % 101;
int user = 0;
int counter = 0;
std::string guess();
int main(void) {
std::string guess();
return 0;
}
std::string guess() {
std::cout << "Enter a number between 0 & 100: ";
std::cin >> user;
if(!(std::cin >> user)) {
return "You entered a non-numeric. Try again. Tries will not be added.";
std::cin.clear();
std::cin.ignore(10000, '\n');
std::string guess();
}
else {
if(user == computer) {
std::cout << "You guessed the right number of " << computer << " in " << counter << " tries.\n";
}
else {
if(user < computer) {
return "The answer is higher. Try again.";
}
else if(user > computer) {
return "The answer is lower. Try again.\n";
}
counter++;
std::string guess();
}
}
}
Note that I am very much a novice programmer, and the issue is probably quite simple and obvious, but I just can't see it. Thanks.
The problem is, that your often write std::string guess(); in order to call your guess() method (e.g. in main. But that doesn't call the method. What it actually does is to declare a new function guess, which is never called (see also Most vexing parse). To only call the method simply write guess();, or auto result = guess(); if you actually want to use the return value.
Also there is an error in this part of your code (see comment):
if(!(std::cin >> user)) {
return "You entered a non-numeric. Try again. Tries will not be added.";
// the following lines are never executed, since you already returned.
std::cin.clear();
std::cin.ignore(10000, '\n');
std::string guess();
}
Issue
The issue is indeed simple and obvious:
std::string guess();
It's obvious that you would like to call your "guess" function, but instead you've just declared it inside "main" and inside "guess".
These declarations are similar to the declaration that you made on the next line after int counter = 0;. It tells compiler that if it encounters call to the function named "guess" it should know that it is a function that takes no arguments and returns std::string.
So, the issue is that instead of calling a function, you declared it several times;
Solution
When you want to call your function you should do it like this:
std::string result = guess();
But since you return some message from guess() I think you should add output after that:
std::cout << result << std::endl;
Actually, I think it would be better to remove return value altogether. In order to do that you should modify "guess" function in a following way:
change return type from std::string to void
replace return with std::cout <<.
Many mistakes.
Firstly you don't need string return type.
So change std::string guess() to void guess()
Then use cin.fail() instead of !(cin>>user)
Also use else if rather than
else{
if{
To generate random number, firstly intialize seed and that can't be done globally, so generate random number in main and pass it in guess function.
To summarize here is the code
#include <iostream>
#include <cstdlib>
#include <string>
#include<ctime>
int user = 0;
int counter = 0;
void guess(int computer);
int main(void) {
srand(time(NULL));
int computer = rand() % 101;
guess(computer);
return 0;
}
void guess(int computer) {
std::cout << "Enter a number between 0 & 100: ";
std::cin >> user;
//std::cout<<computer<<std::endl;
if(std::cin.fail()) {
std::cout<< "You entered a non-numeric. Try again. Tries will not be added.";
std::cin.clear();
std::cin.ignore(10000, '\n');
guess(computer);
}
else if(user == computer) {
std::cout << "You guessed the right number of " << computer << " in " << counter << " tries.\n";
return;
}
if(user < computer) {
std::cout<< "The answer is higher. Try again.\n";
}
else if(user > computer) {
std::cout<< "The answer is lower. Try again.\n";
}
counter++;
guess(computer);
}

Nesting int main() inside int main()

I am trying to make the simplest of all games, but with a loop function.
I'm given the error "a function-definition is not allowed here before '{', as well as a whole list of [Error] expected '}' at end of input.
Am I not allowed to nest int main() within another? Is that my issue at all? How do I accomplish this code without the nesting?
My knowledge and experience extend no more than a few chapters in two books.
#include <iostream>
#include <cstdlib>
#include <ctime>
using namespace std;
int main()
{
char again = 'y';
while (again == 'y')
int main()
{
srand(static_cast<unsigned int>(time (0)));
int secret = rand() % 100 +1;
int tries = 0;
int guess;
cout << "\tGuess the random number\n\n";
do
{
cout << "Enter a guess: ";
cin >> guess;
++ tries;
if (guess > secret)
{
cout << "Too High!\n\n:";
}
else if (guess < secret)
{
cout << "Too Low!\n\n";
}
else
{
cout << "\nThat's It! You go it in " << tries << " guesses!\n";
}
} while (guess != secret);
}
cout << "\n\tWould you like to play again? (y/n): ";
char again;
cin >> again;
}
Your issue is nesting a main function inside of the existing main function. (This is not allowed.) In general, (With the exception of some stuff you can do with structs/lambdas which approximate that kind of functionality) you shouldn't nest functions inside of each-other. If you merely remove the function declaration, then your code should work fine:
#include <iostream>
#include <cstdlib>
#include <ctime>
using namespace std;
int main()
{
char again = 'y';
while (again == 'y')
{
srand(static_cast<unsigned int>(time (0)));
int secret = rand() % 100 +1;
int tries = 0;
int guess;
cout << "\tGuess the random number\n\n";
do
{
cout << "Enter a guess: ";
cin >> guess;
++ tries;
if (guess > secret)
{
cout << "Too High!\n\n:";
}
else if (guess < secret)
{
cout << "Too Low!\n\n";
}
else
{
cout << "\nThat's It! You go it in " << tries << " guesses!\n";
}
} while (guess != secret);
cout << "\n\tWould you like to play again? (y/n): ";
cin >> again;
}
}
As far as I know, you cannot nest int main() inside of int main() for a number of reasons. In general, you can't define one function inside of another (defining "locally"). However, even if you can, your desire to do so should be a massive red flag that your design is off.
NOTE: As Nathan Oliver pointed out in the comments, you can forward-declare a function "locally" (within another function), but the actual implementation must be outside. Even doing this, you should usually second-guess your design at this point.
You need to be asking yourself what you're trying to do.
Are you wanting to group code together under a function to call repeatedly? Then create a separate function (with a different name) outside of main().
Are you wanting to repeat code? If so, you need a loop or a recursive function structure.
Are you wanting to split up some behavior into several functions, but hide all but one function involved? If so, look into classes (not necessarily objects - you can also have static classes.)
Those are just three of many possibilities, and deciding exactly what you want to do and how you want to do it is your responsibility alone to decide, as a programmer.
Brief recap: as far as C++ (and C) are concerned, if you're trying to declare any function inside any other function, you are doing something seriously wrong in design.
On a more technical note, you should also understand precisely what int main() is. It is a special function that is the entry point for your program. No C or C++ program can run without an int main().
You have to have a single instance of this function in main.cpp in order for your program to work. If you have more than one int main(), the computer cannot likely will not be able to find the entry point.
Besides that, having more than one function called main() anywhere in your code is a great way to confuse yourself and others.
In short, you should only have one int main() per program, no exceptions.

I think I'm trying to pass data wrong in my variables? Novice coder inside

I started learning some basics of C++ and I wanted to write some code to practices what I've learned. I wanted to make a class and some functions. It's supposed to be a title screen to start a text game, except there is no game...yet :P
Whenever I enter 1 to start so it displays "Good Work" it just does nothing after I hit enter.
Any point in the right direction would be great. I've been watching videos and reading tutorials on functions, it doesn't seem to cover the problem I'm having...
#include <iostream>
#include <string>
using namespace std;
//Function Protos
void keyError();
int userInput(int x);
//class library
class Title
{
bool nSelect;
int x;
public:
void titleScreen()
{
while(nSelect)
{
cout << "Welcome to Biggs RPG!" << endl << "1. Play 2. Exit" << endl;
userInput(x);
if (userInput(1))
nSelect = 0;
else if (userInput(2))
{
cout << "Closing program..." <<endl;
nSelect = 0;
}
else
keyError();
}
}
};
int main()
{
Title displayTitle;
displayTitle.titleScreen();
cout << "Good work";
return 0;
}
void keyError()
{
cout << "Meow? Wrong input try again." << endl;
}
int userInput(int x)
{
x = 0;
cin >> x;
return x;
}
There are numerous stylistic and technical problems. Try learning from resources recommended in The Definitive C++ Book Guide and List.
Here is a start…
#include <iostream>
#include <string>
// "using namespace std;" is poor practice. Better to write out std::
/* Unless you will have two title screens at the same time,
this should probably be a namespace, not a "singleton" class. */
namespace Title
{
int nSelect;
void titleScreen()
{
do {
// prompt for input
std::cout << "Welcome to Biggs RPG!\n" "1. Play 2. Exit\n";
// get ready to accept input, even if there was an error before
if ( ! std::cin ) {
std::cin.clear(); // tell iostream we're recovering from an error
std::cin.ignore( 1000, '\n' ); // ignore error-causing input
}
// repeat if invalid input
} while( ! std::cin >> nSelect || ! handleInput( nSelect ) );
The difference is that you want to ask for input, then handle it. The code you posted asks for input again each time it checks what the input was.
This is a do … while loop, so it executes at least once and then repeats as long as the condition at the end is true. If the user gives an invalid input, then ! std::cin evaluates to true. Then the policy of C++ is to stop returning any input until you call std::cin.clear(), which signals that you are going to try again. ignore then gets rid of the invalid input. Then ! std::cin >> nSelect tries to read a number, and if that operation is successful, call handleInput (which you must write) which should return false if the input was invalid. So if reading a number fails, or the wrong number was entered, the loop goes again.
You should compare the return value of userInput with 1 or 2, like this:
int userInput(void);
//class library
class Title
{
bool nSelect;
int x;
public:
void titleScreen()
{
nSelect = true;
while(nSelect)
{
cout << "Welcome to Biggs RPG!" << endl << "1. Play 2. Exit" << endl;
x = userInput();
if (x == 1)
nSelect = false;
else if (x == 2)
{
cout << "Closing program..." <<endl;
nSelect = false;
}
else
keyError();
}
}
};
and define userInput as:
int userInput(void)
{
int x = 0;
cin >> x;
return x;
}
I sense confusion about the difference between parameters and return values. When you define a function as
int userInput(int x) {
...
You pass a value to the function (x) and return a value with the return statement. In your case you don't need to pass a parameter to your function; you need to return a value. You access this value by assigning it to another variable:
theResult = userInput(123);
But it doesn't matter what value you pass to the function; you might as well use
int userInput(void) {
...
In which case you can use
theResult = userInput();
Now just to confuse you, it is possible to pass the address of a variable as a parameter to a function. You can use that either to access data (usually a "larger" block of data like an array or struct) but it can also be used to provide a place where a return value is stored. Thus
void squareMe(int *x){
*x*=*x;
}
Would return the square of the number pointed to in that location. You could then do
int x=4;
squareMe(&x);
cout << x;
Would print out 16 (!). This is because the function looks at the contents of the address (&x is the address of the variable x), and multiplies it by itself in- place.
I hope this explanation helps.