My program's main function displays a switch menu. When option 1 is entered, a function is called that "shuffles" an array of "cards". After the shuffling is complete, that function returns the program to the beginning by calling main(), so that the menu is shown again.
The problem I have with this is that option 4 of the menu writes the shuffled array to a file. But when the cards are shuffled and then the program is restarted, the array data is lost, and therefore the outputted file is all junk. Is there a way to restart main() WITHOUT that data being lost?
I am in a class and am limited in the tools I can use, so only the most basic code will be acceptable. Basically, I'm looking for something like goto but a little safer (goto, by the way, is also forbidden in this class).
It's actually not a good idea for a C++ program to call its own main function. In fact, this leads to undefined behavior, which means that you have no guarantees about the behavior of the program. It could crash, or proceed with corrupt data, or format your hard drive, etc. (that last one is unlikely, though).
I think that this reflects a more fundamental problem with how your program works. If you want data to persist across functions, you need to place that data somewhere where it won't get clobbered by other functions. For example, you could put the data in the heap, then pass pointers to the data around. Or, you could define it as a local variable in main, then pass it down into functions and have those functions return when they're done. You could also consider making objects representing the data, then passing those objects across the different functions.
Without seeing your code, I doubt I can give a more specific answer than this. When designing programs, keep the data flow in mind. Think about what data needs to go where and how you're going to get it there.
Hope this helps!
Why are you calling main recursively (which, by the way, is forbidden by the standard)? Just use a loop (e.g. a do ... while) to repeat the part of your main that needs to be repeated, keeping the variables that must not be resetted (and their initialization) outside the loop.
The main() function should not be called recusively.
You can encapsulate your game loop into a while() function.
Take a look at this example :
#include <iostream>
#include <string>
using namespace std;
int main()
{
bool exitGame = false;
// Game Loop
while(!exitGame) {
// Display menu
cout << "Menu :" << endl;
cout << "- Shuffle : press 1" << endl;
cout << "- Option 2 : press 2" << endl;
cout << "- Option 3 : press 3" << endl;
cout << "- Exit : press 4" << endl;
cout << "Enter your choice : ";
// Get user input
string choosenValue;
cin >> choosenValue;
cout << endl;
// Process user input
if (choosenValue == "1") {
cout << "You selected 'Shuffle'." << endl;
// Do cool stuff here !
} else if (choosenValue == "2") {
cout << "You selected 'Option 2'." << endl;
// Do cool stuff here !
} else if (choosenValue == "3") {
cout << "You selected 'Option 3'." << endl;
// Do cool stuff here !
} else if (choosenValue == "4") {
cout << "You selected 'Exit'." << endl;
exitGame = true;
} else {
cout << "Wrong value." << endl;
}
cout << endl;
}
return EXIT_SUCCESS;
}
Move main body to another function 'myMain' and call it insteadOf main.
Related
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.
I've been working on a Shape program lately ( Some of you might remember my other questions about this... ;/ ) And I have a tiny problem which I want to fix.
In my Menu class, which holds all the functions related to the menu. I have a unique_ptr vector with the type of my base class Shape which holds all of the newly created objects ( Circles, Rectangles, ect )
protected:
vector<unique_ptr<Shape>> _shapes;
One of the functions that I want to create is supposed to change the values of the variables in a given shape based on it's index. To do so, I was planning to print the vector to the user, and then let him to choose the index of the shape that he wants to change.
void Menu::printShapes() const
{
int i = 0;
for (auto p = _shapes.begin(); p != _shapes.end(); p++, i++)
{
cout << i + " ";
(*p)->printDetails();
cout << endl;
}
}
The problems lays in my main program which is going to use my Menu functions. Because I don't want the user to be able to enter values which are outside of my vector, I have to check if the given input is between 0 and the size of the vector. But I cannot access this info from my main function without making the vector public or make a return statement from the printShapes() function, which will make the code messy and not intuitive as I want it to be.
So my question is: Is there a way to find the size of the vector at the Menu function from the main function without making the changes I stated above? Because in the end I want to be able to just do menu.printShapes() and then let the user to choose the index of the shape that he wants to change
this is my main function as of now:
Menu menu;
int input = 0, wait = 0;
while (input != 4)
{
cout << "1: Add New Shape: " << endl;
cout << "2: Modify Existing Shape: " << endl;
cout << "3: Delete All Shapes: " << endl;
cout << "4: Exit: " << endl;
while (input < MIN || input > MAX)
{
cin >> input;
cin.ignore(numeric_limits<streamsize>::max(), '\n');
std::cin >> wait;
}
switch (input)
{
case 1:
{
cout << "1: Circle: " << endl;
cout << "2: Rectangle: " << endl;
cout << "3: Triangle: " << endl;
cout << "4: Arrow: " << endl;
while (input < MIN || input > MAX)
{
cin >> input;
cin.ignore(numeric_limits<streamsize>::max(), '\n');
std::cin >> wait;
}
menu.createShape(input);
}
case 2:
{
/*
I want to be able to access the size of the vector from here
So I could do something like that:
menu.printShapes();
while (input < 0 || input > vectorSize)
{
:Get the index of the shape that the user wants to modify
}
Instant of doing
size = menu.printShapes();
*/
}
}
}
You're way overthinking this.
You just need to add a public function that returns the current size of the vector:
// Declaration in your class
size_t numberOfShapes() const;
// Definition
size_t Menu::numberOfShapes() const
{
return _shapes.size();
}
. Then, when you want to know the size, call that function.
menu.printShapes();
while (input < 0 || input > menu.numberOfShapes())
{
// Get the index of the shape that the user wants to modify
}
Simple!
By the way, I think you meant >= there, not >.
You have at least a few options; depending on the details of the modify-existing-shape operation.
The easiest thing would probably be to have your Menu type expose a method to tell you how many shapes it's managing. I agree you shouldn't make the vector public because the program doesn't need to know it's a vector specially, but if "knowing how many existing shapes the menu is managing" is a requirement (which it seems to be) then exposing it seems reasonable.
Alternatively, depending on the return type of the modify operation you could return an optional or a variant. If you have 7 shapes and I ask you to modify the 6th then you might tell me that it worked or maybe the new dimensions, but if I ask you to modify the 9th you might tell me it's an invalid index.
The difference becomes whether to obligate the caller to be informed and ask a valid question, or whether you want to be more robust and answer and handle a broader domain of questions. I don't think it makes a big difference in this case but I tend toward the second kind of solution simply because it means any potential caller is protected from going out of range instead of all of then having to check the count then do their own validation.
For my homework assignment I'm supposed to make a create-your-own-adventure story. There are certain words in the text that are in all caps to represent boolean values that I need to display at the end if the player got them, like a status effect or something. I'm having trouble figuring out how to pass the booleans to the functions so that it makes it to the end of the program where I can display it. My program has functions within functions.
I've tried making the function that sets the boolean to true a boolean itself, then returning the boolean but that just ends the program it seems. I've also tried passing it through the first function call to see if it reaches the second but it doesn't seem like it wants to.
void A1();
bool A100(bool INTIM);
void A167();
void A232();
void A290();
void A13();
void A212();
void A173();
void A159();
void A161();
int main() {
bool INTIM;
A1();
cout << INTIM << endl;
return 0;
}
void A1()
{
int choice;
cout << "Well, Mr Artanon, ...\n 1. ’It’s you who’ll get a rare cut
across that corpulent neck of yours if you don’t speed things along, you
feckless blob of festering lard.’\n 2. ’Surely in such an industrious
kitchen, there must be a starter or two ready to send along and sate His
Abhorentness’s appetite?’\n (enter a menu option): ";
cin >> choice;
while (choice != 1 && choice != 2)
{
cout << "Enter in a valid choice (1 or 2)";
cin >> choice;
}
if (choice == 1)
{
A100();
}
if (choice == 2)
{
A167();
}
}
bool A100(bool INTIM)
{
int choice;
INTIM = true;
cout << " Repugnis turns a paler...\n 1. Onwards, Mr Artanon.\n (enter
in a menu option): ";
cin >> choice;
while (choice != 1)
{
cout << "Enter in a valid option (1)";
}
return INTIM;
A232();
}
What I'm wanting to happen is, the bool INTIM to be passed along so i can display it back in main with the cout statement. I know it will just be a 1 or 0 at the end but I'm just trying to get it to show up at least in the end when I display it. Again there are functions within functions in this program and that might be my problem but I wouldn't think so. There is also functions that come after this, this is not the end of the program and if I need to post the whole thing I will
Calling A100 as written, you need to pass in INTIM and accept the return value
INTIM = A100(INTIM);
But... The initiqal state of INTIM is never used, so you could
INTIM = A100();
and change A100 to look more like
bool A100()
{
int choice;
cout << " Repugnis turns a paler...\n 1. Onwards, Mr Artanon.\n (enter in a menu option): ";
cin >> choice;
while (choice != 1)
{
cout << "Enter in a valid option (1)";
cin >> choice; // added here because otherwise choice never changes
// and this loop will go on for a long, long time.
}
A232(); // moved ahead of return. Code after a return is not run
return true;
}
But since A232 is called and may set additional flags you cannot return, you have a design flaw: What if A232 also modifies a boolean? You can only return one thing from a function. You could pass A232's boolean in by reference, but what it A232 then calls B484 and it also has a boolean?
You don't want to have to pass around every possible boolean, that would be a confusing mess, so consider making a data structure that stores all of your booleans to pass around.
And that leads to an even better idea: encapsulating the booleans and the functions in the same data structure so that you don't have to pass anything around; it's all in the same place.
Do I need to pass them [the boolean results] to the functions?
Often, but not always, it is my preference to pass them by reference, and yes, it can get to be a big chain thru many functions. sigh.
But your question is "Do you need to pass them ...".
The answer is No.
Because
a) you have tagged this post as C++, and
b) the key feature of C++ is the user-defined-class.
Consider declaring every 'adventurous function' of your story within a class scope.
Each 'adventurous function', as an attribute of the class, is implemented with one 'hidden' parameter, the 'this' pointer to the class instance.
So .. if you place all your 'result' booleans as data attributes of the class, invoking any 'adventurous function' will also 'pass' all the class instance data attributes (all your bools!) as part of the invocation. No data is actually moving, just a pointer, the 'this' pointer.
It might look something like this:
#include <iostream>
using std::cout, std::cerr, std::flush, std::endl;
// using std::cin;
#include <iomanip>
using std::setw, std::setfill;
#include <sstream>
using std::stringstream;
#include <string>
using std::string;
namespace AS // Adventure Story
{
class CreateYourOwnAdventureStory_t
{
private:
// diagnostic purposes
stringstream ssUI;
// command line arguments concatenated into one string
// contents: strings convertable to ints to mimic cin
bool INTIM;
// other results go here
public:
int operator()(int argc, char* argv[]) {return exec(argc, argv);}
private:
int exec(int argc, char* argv[])
{
int retVal = 0;
// capture all command line arguments into a string
for (int i=1; i<argc; ++i)
ssUI << argv[i] << " ";
cout << "\n ssUI: " << ssUI.str() << "\n\n\n";
A1();
cout << "\n INTIM : " << INTIM << endl;
// ?more here?
return retVal;
}
void A1()
{
int choice = 0;
cout << "Well, Mr Artanon, ...\n "
"\n 1. ’It’s you who’ll get a rare cut across that corpulent neck of yours "
"if you don’t speed things along, you feckless blob of festering lard. "
"\n 2. ’Surely in such an industrious kitchen, there must be a starter or two "
"ready to send along and sate His Abhorentness’s appetite?’"
"\n (enter a menu option): ";
ssUI >> choice; // cin >> choice;
if (choice == 1) { A100(); }
if (choice == 2) { A167(); }
}
void A100()
{
int choice = 0;
INTIM = true;
ssUI >> choice; // cin >> choice;
cout << "\n\n A100() choice:" << choice
<< " INTIM: " << INTIM << endl;
}
void A167()
{
int choice = 0;
INTIM = false;
ssUI >> choice; // cin >> choice;
cout << "\n\n A167() choice:" << choice
<< " INTIM: " << INTIM << endl;
}
// other action-functions go here
}; // class CreateYourOwnAdventureStory_t
typedef CreateYourOwnAdventureStory_t CreateYOAS_t;
} // namespace AS
int main(int argc, char* argv[]){return AS::CreateYOAS_t()(argc,argv);}
Notes:
This example grabs the command line parameters and appends them to a string stream. The result is use-able in a fashion much like your cin statements.
Did you notice you (probably) will not need forward declarations for your functions? The compiler has to scan a lot of the class declaration to decide various issues, and thus can figure out that A100 (and A167) are actually with-in the scope of AS::CreateYOAS_t::. The functions can still be moved into a cpp file, so you can still take advantage of separate compilation. (and maybe save some effort compiling smaller files, and only the changed files.)
Did you notice that the functions accessing INTIM simply use the bool, without needing any 'this->' to de-reference?
Main invokes a simple Functor. Nothing else. Main invokes operator(). Simple, minimal. The ctor and dtor are currently default. If you need to use the ctor to initialize results or other intermediate info, I would simply add it near the operator() implementation.
PS: You mentioned using bools to return results. You might as, an alternative, consider using a stringstream ... a single stream with text ... use like a log for capturing the ongoing game, or for a single simple overall report to the user.
Good luck.
Been trying to find a way through this. I am new to C++ and creating a simple program to get the user data, validate and cout to the screen. What i'm trying to do is to have the one function use pointers to get the users input and display back to them. This may have been answered before but I haven't had much luck finding it.
So far i have the below code
#include <iostream>
using namespace std;
void userData(int&);
int main(){
int a = 0;
int * kmpointer;
int * dayspointer;
userData();
cout << "You ran " << userData(kmpointer) << endl;
cout << "in " << userData(dayspointer) << "days!!" <<endl;
}
void userData(int& i){
cout << "Enter how Many Km's you ran:";
while (true)
{
cin >> kmpointer;
if ((cin) && (kmpointer >= 0) && (inputYear <= 100))
break;
cin.clear();
cin.ignore( 100, '\n' );
cout << "That can't be right!\n";
cout << "Enter how Many Km's you ran:";
}
cout << "How many days in a row did you run?";
while (true)
{
cin >> dayspointer;
if ((cin) && (dayspointer >= 1) && (dayspointer <= 100))
break;
cin.clear();
cin.ignore( 1000, '\n' );
cout << "Thats way to much!";
cout << "How many days in a row did you run? ";
}
}
IMO, you should start with some reading about C++. You are missing some basic concepts and trying too complex exercises for your level.
1
function is not declared/defined.
2
userData is declared accepting a parameter, but used without.
3
The problem you face is related probably with what we call scope: A variable is only existing and visible within its scope (usually enclosed by { and }.
In your case, kmpointer and dayspointerare only visible within the main function and thus, you cannot use them in userData.
To solve that, I suggest you to pass those variables as parameters for userData.
4
Pointers, references, values: They are different. You are saving the user input as a pointer address, which is indeed problematic.
General
In general, your code is full of mistakes. Try a Hello world! and continue from there steps by steps.
Focussing on the specific question you asked (though as observed you have other problems in your code), don't use pointers, use references.
Before we get to that this
cout << "You ran " << userData(kmpointer) << endl;
won't compile, since as you know userData is a void function, so applying << to it makes no sense. It's void so there's nothing to stream.
You said you wanted to pass parameters into the function and let them be changed so do that. Then display the variables afterwards. (Not the "result" of a void function call).
Correctly getting the user input is a separate question which has been answered before.
#include <iostream>
using namespace std;
void userData(int& i, int& j, int& k);
int main() {
int a = 0;
int kmpointer;
int dayspointer;
//Here we call our function, ONCE
userData(a, kmpointer, dayspointer);
//Here we display what values we now have
//after calling the function, ONCE
cout << "You ran " << kmpointer << endl;
cout << "in " << dayspointer << " days!!" << endl;
}
//simplified to demonstrate changes to the reference parameters
void userData(int& i, int& j, int& k) {
//Here we have three parameters which we refer to as i, j and k
// They may have different names ousdie in the calling code
// but this function (scope) neither knows nor cares
j = 42;
k = 101;
}
I have a while statement that keeps repeating the text without giving the user a chance to input another value for action. What am I doing wrong? It still doesn't ask for input. I need for the code to display the text once, then ask for input. Presumably, if you typed anything but 1 it would repeat the sequence. But as it stands it simply kicks you out of the loop without the chance to correct the action (As of the last edit, see below.)
int action = 0;
while (action != 1)
{
cout << " No you must look it might be dangerous" << endl;
cin >> action;
}
One suggestion was:
while (action != 1)
{
cout << " No you must look it might be dangerous" << endl;
cin >> action;
cin.ignore();
}
That still produces text over and over.
while (action != 1)
{
cout << " No you must look it might be dangerous" << endl;
if (!(cin >> action))
// ...problems in the I/O stream...
break;
}
This one kicks you out without a chance to input a new action.
If you type a character that is not white space and can't be part of an integer, then you have an infinite loop. Each attempt to input to action fails on the invalid character without changing the value stored in action.
You could write:
int action = 0;
while (action != 1)
{
cout << " No you must look it might be dangerous" << endl;
if (!(cin >> action))
// ...problems in the I/O stream...
break;
}
This will handle EOF and alphabetic characters more gracefully than a continuous loop. You might need to set a flag or return an error condition from the function or do something else other than break out of the loop. Always check your inputs for success.
You might also consider outputting the value you're getting stored in action in the loop, so you can see what is happening:
int action = 0;
while (action != 1)
{
cout << " No you must look it might be dangerous" << endl;
if (!(cin >> action))
// ...problems in the I/O stream...
break;
cerr << "Action: " << action << endl;
}
This might tell you something useful too.
Please show a complete little program that illustrates your problem — an SSCCE (Short, Self-Contained, Correct Example).
For example, I'm testing with:
#include <iostream>
using namespace std;
int main()
{
int action = 0;
while (action != 1)
{
cout << " No you must look it might be dangerous" << endl;
if (!(cin >> action))
{
// ...problems in the I/O stream...
break;
}
cout << "Action: " << action << endl;
}
cout << "After loop" << endl;
if (!cin)
cout << "cin is bust" << endl;
else
cout << "Action: " << action << endl;
}
That's no longer minimal code — the material after the loop is merely telling me what is happening. But it does help me ensure that my code is doing what I expect.
What does your equivalent code look like, and what are you typing in response to the prompts — and especially, what are you typing before you get to this code fragment (and what other input activity is going on before you get here)?