C++ Ways to shut down a program - c++

Before you start wasting your time on me, please keep in mind that this question is more about knowing if this shutdown is legit enough.
Alright.
I read all kinds of ways to shut down a program. I KNOW that it's always best to shut down the program, at the end! So as i said, i read all kinds of topics, but i couldn't really find one that i understood correctly. So i kinda came up with my own way. I just want to make sure it's an okay method.
int main()
{
cout << "Welcome to my fantastic program!" << endl;
cout << "You're the first one to experience my command program!" << endl;
cout << "Let's try with a simple command. Try typing help" << endl;
while (running == 1) {
commands();
if (running == 0) {
exit(0);
}
}
return 0;
}
So i want you to focus on the while loop. This is my method.
void commands()
{
cin >> command;
if (command == "help")
{
cout << "-------------------------------" << endl;
cout << "-this is the <HELP> section----" << endl;
cout << "-exit (exits the program.)" << endl;
cout << "-Stay tuned for more commands--" << endl;
cout << "-------------------------------" << endl;
}
else if (command == "exit")
{
running = 0;
}
else
{
cout << "The command does not exist: " << command << endl;
}
}
And this is my command function. As you see, this changes "running" to 0 (or false). I hope i made this understandable enough.
Thanks.
EDIT: All i want to know is, if this is an okay method :)
FINAL EDIT: Alright! I changed "exit(0);" to "return(0);". So i guess this is a okay good method! Thanks for your help! :)

Using exit() in a program is legal. Though it's generally a bad idea. But if the program is stuck without a way back for some weird reason, you can do it.
Using exit in main() is rude: I just can't think of a sane reson not to use return instead.
The difference between exit() and return from main is that the former will leave all local objects in stack frames from main to the call point hanging, destructor not called. Only the static/global objects get proper shutdown. It may surprise some portions of the code, and leave important things not done.
As C++ has fine exceptions, I'd consider it preferable to replace exit() with throwing something that manages up to main, where regular return happens.

The if (running == 0) but is pointless!
while (running == 1) {
commands();
}
return 0;
Does exactly the same - once running is 0 it falls out the bottom of the loop, and main returns. The whole idea of the global running is getting into side effect programming, which is a bad thing!

Given the boundary conditions in the question exit() does what you want it to. It terminates the process normally, performing the regular cleanup for terminating programs (atexit(), destroying objects without automatic storage etc).
You don't really want to use a global running, so I would rather suggest checking the return parameter of commands().
say
int commands()
{
if(wanna_exit)
return 1;
else
return 0;
}
And if you for some reason cannot just let commands() break the while loop (For example by checking the return parameter and setting running to 0 if it is 1), and you want to exit the program instantly rather than finishing evaluating the rest of the while loop then exit() is ok (although in this particular case return is better (since you are in main in the example) ). Just try to avoid having running as global - might seem innocent right now, but can turn mean later :).

Related

Way to detect number rather than letter from string. (using istringstream currently)

I made a simple game program, and a requirement calls for a option for the player to undo a number of moves (undo n).
I have the user enter in a command (undo n) and it takes the back half and puts it into an int. Basically, I want the program to stop the user if they entered in anything but a number. So if the user typed in undo f it won't convert f into it's number form (or at least that's what I think it would do) but it'll cause an error. I searched for a while and couldn't find anything that worked or made sense to me.
try {
int undo;
istringstream is(userInput.substr(5, userInput.length()));
is >> undo;
for (int numOfUndos = undo; numOfUndos > 0; numOfUndos--) {
board.UndoLastMove();
}
moveValidated = true;
}
catch (exception &e) {
cout << "/-----------------------------/" << endl;
cout << e.what() << endl;
cout << "/-----------------------------/" << endl;
}
If possible, I would like to just use how I currently have it or with cin. Also, forgive me, but I'm still learning C++ and don't know many advanced techniques, so if there is a complex way to do this forgive me if it takes me a bit to understand.
Thanks for any help in advance.
This worked for me. Thanks again.
The game description is not really relevent to your problem: how to
convert a string into an integer and check if it failed. To do that,
if (is >> undo) { worked } else { failed } Does UndoLastMove throw an
exception? – Neil Kirk

About boolean identifier inside a loop I think

I've read a book by Mark Lee, C++ absolute beginner, and one of the code snippet is :
while(true)
{
cout << description.c_str() << "\n\n";
int response = 0;
do
{
cout << "What would you like to do?\n";
if(enemy)
cout << "1) Attack the evil "
<< enemyName.c_str() << "\n";
else if(!enemy)
cout << " 1) Move to the next room.";
if(treasure)
cout << " 2) Pick up the "
<< treasureName.c_str() << "\n";
cin >> response;
}while(response < 1 || response > 2);
switch(response)
{
case 1 : if(enemy)
{
enemy = !enemy;
cout << "You slay the deadly "
<< enemyName.c_str() << "\n";
}
else if(!enemy)
return;
break;
case 2: treasure = !treasure;
cout << "You pick up the "
<< treasureName.c_str() << "\n";
break;
}
}
I think you can ignore about what this program intention is, but the question is, why the part of "while(true)" is exist ? I think, there are no ways out of the loop, right ? Because, I think the "true" value is always return 1, and the "while(true)" part is same with "while(true == 1)", so this loop is like infinity loop, am I wrong or ? Any help is appreciated.
Yes:
this loop is like infinity loop
You're correct in that while(true) is an instruction to loop forever.
However, there are a few other ways to exit loops:
A return statement will exit the function (and consequently also terminate the loop)
A break statement will exit the closest for, while or switch statement.
A goto statement might cause the code to jump to a label outside the loop
An exit() call will cause the whole program to terminate.
A throw statement will throw an exception that will break out to the nearest appropriate catch statement (which might be outside the loop).
In this case, the return; near the bottom of the loop causes the function to exit.
The break; statements do not cause the loop to stop, because they belong to the switch.
A caveat on the use of goto - many programmers consider it poor style, as it can lead to code that is difficult to follow. There is quite a bit of further discussion on this question. In C++, typically throw is more appropriate for situations where goto might be used.
However, there are situations in pure C where goto can be very useful. This answer provides an excellent overview of why goto is historically considered poor style, and even provides some examples of where it might be appropriate to use goto.
Of course, a good rule for beginners might be "pretend goto doesn't exist". Especially in C++.
If you look closely, there is a
return;
statement in the code. This will exit the loop and the function the loop is in.
(This is worth answering since it has fooled at least one 5,000 reputation user and therefore demonstrates the importance of writing code that is clear).
The return statement is the loop terminator. This will exit the function.
It's buried deep within the function. I'd criticise the code therefore for that style: it's hard to follow and difficult to debug.
The only exit from the while(true){...} is the return statement, which terminates the surrounding function.
I don't know the book, but I've never seen another suggestion of writing if statements this redundant way:
if(enemy)
{ ...
}
else if(!enemy)
{...
}
Redundancy is usually to be avoided since it makes maintenance more difficult.
And I very much dislike:
case 2: treasure = !treasure;
cout << "You pick up the "
<< treasureName.c_str() << "\n";
This will let you pick up the treasure, but you stay in the loop and can select '2' once more, telling you "You pick up the x" once more, but negating variable treasure once more. Hmm, let's hope this isn't a full quote from the book!

C++ For Loop not Exiting

I have a for loop, a very simple one, in my program, and I want it to loop through and do something for some minimum number of times. However, the loop simply...stops. But does not move on to the next thing in the program. For instance, when min is 9, it runs for i=0 to i=8, then freezes. It should exit the for loop, but it does not execute the next print instruction, nor does it execute the loop again. It just stops. The program hangs, doing absolutely nothing as far as I can tell. I don't understand why this is.
The merged.put() function I want to execute just puts x or y in merged, depending on the condition. That part works. This is just a small part of a much larger program. sp1, sp2, and merged are all defined elsewhere.
int i;
int x;
int y;
for(i=0; i < min; i++)
{
cout << " here " + convert(i);
x = sp1.get_num(i);
y = sp2.get_num(i);
if(x >= y) {
merged.put(x);
}
else {
merged.put(y);
}
cout << " end" << endl;
}
cout << "out";
EDIT: I'm not posting the entire code, it's several hundred lines long. Type of min is int. The reply down there was helpful, when << endl was added to the last print statement, it printed. My problem now appears to be here, getting stuck on the second while, because I was not incrementing i. Shame on me...thanks for the help. (This comes directly after the above code)
if (sp_large == 2) {
cout << "1" << endl;;
while (i < sp2.get_size()) {
merged.put(sp2.get_num(i));
}
}
else {
while (i < sp1.get_size()) {
merged.put(sp1.get_num(i));
}
cout << "2" << endl;
}
EDIT: Problem solved, thanks for the help.
I'm betting that it's actually a later part of the program that is hanging.
This line:
cout << "out";
just puts "out" on the output-buffer, and won't actually print "out" until the output-buffer gets flushed. (Which could happen immediately, but is not likely to.) Change that line to this:
cout << "out" << endl;
and "out" will be printed as soon as that line is run. This will help you figure out if the program is hanging before it gets to that line, or somewhere later on.

c++, sleep, and loops

Ok, this is just out of curiousity, but why does the sleep function NOT work in a loop, or how can I Get it to work in a loop?
for(int i = 0; i < 5; i++) {
cout << i << endl;
sleep(2);
}
cout is buffered, meaning its contents aren't always written to the console right away. Try adding cout.flush() right before sleep(2);
If that isn't working for you you could try this code:
#include <iostream>
#include <windows.h>
...
for(int i = 0; i < 5; i++) {
cout << i << endl;
Sleep(2000);
}
Have you tried unrolling the loop to see if that behaves the same way?
cout << 1 << endl;
sleep(2);
cout << 2 << endl;
sleep(2);
// Etc.
Assuming that behaves the same way, even though std::endl is supposed to flush the buffer, it really does look like dave.kilian has the right idea that cout isn't getting flushed until the program (presumably) terminates.
In that case, try doing the std::flush and see if that helps - it's possible you have a bug (missed feature?) in your standard library.
Another thing to try is to redirect the output to a file while watching it with tail -f in another window. See if the same delay occurs when redirected.
Finally try playing with the compiler's optimization level and see if that changes the results.
In my humble opinion, this program should work correctly. Maybe your std::cout is redirected somewhere else? You don't call the correct sleep() function (but no header provided)? Or other problem? But it should work.
Dave has already given you the answer, so I won't touch on that. However, if its purely for debugging or prototype code, you could also pipe the output to std::cout's sibling, std::cerr, which is unbuffered to begin with. This means you do not need to call flush explicitly and you do not need to add an endl to your output.
Try Sleep() instead of sleep()

Variable not accessible within an if statement

I have a variable which holds a score for a game.
My variable is accessible and correct outside of an if statement but not inside as shown below
score is declared at the top of the main.cpp and calculated in the display function which also contains the code below
cout << score << endl; //works
if(!justFinished){
cout << score << endl; // doesn't work prints a large negative number
endTime = time(NULL);
ifstream highscoreFile;
highscoreFile.open("highscores.txt");
if(highscoreFile.good()){
highscoreFile.close();
}else{
std::ofstream outfile ("highscores.txt");
cout << score << endl;
outfile << score << std::endl;
outfile.close();
}
justFinished = true;
}
cout << score << endl;//works
EDIT:
have realised my problem, when I was printing out it looped through many times so I did not see that all of them for the first loop didn't work, hence I thought the others were working when in fact they were not for the first iteration.
This is not a problem relating to the scope of the variable.
It could be several things:
Memory corruption somewhere
Multi threading relating problem
Something else...
Are you sure you are looking at the same iteration where the score value works before and after but not inside? Maybe put some more detailed logging instead of simply outputting the score itself.
Try printing cout << score << "#" << &score << endl; each place you currently print score. This will let you check if you're actually looking at the same variable.
If the addresses are different, you're accidentally shadowing your score variable somewhere - gcc has -Wshadow to catch that.
If the addresses are the same then the variable is getting corrupted somehow. Most debuggers have a memory breakpoint feature, so you can set the debugger to break when the memory in score changes and find the culprit.
With the amount of code you have attached there is nothing to indicate there is a problem in the code. As Brian says it is something else
Can you try this in your debugger and see what happens ? The idea is to simplify the problem as much as possible and try to get the minimal amount of code that replicates the problem.
What does this do ?
cout << score << endl; //works
if(!justFinished)
{
cout << score << endl; // doesn't work prints a large negative number
}
cout << score << endl; //works