Console Closing Down

Pages: 1234... 7
I think the ‘brilliant’ thing about Ropez’s suggestion is to do with the fact it uses the destructor of a class to keep the window open even if the program terminates abnormally. Ropez has the comment // Whatever code you prefer to keep the program running, e.g. prior to the system("pause"); so you do not have to use system("pause"), you could output your own message and wait for a key press.
If I may answer that question: Whether to use "system()", "cin.get()", "cin.ignore()" or whatever was irrelevant in my post. That was pointed out by the comment
Whatever code you prefer to keep the program running
.

What Douas referred to as "brilliant" was not what kind of statement that was used to stop the program, but where the statement was placed, inside a destructor of an object placed on the stack. This forces the compiler to generate a call to this code, no matter how the program returns from the main function (even if an exception was thrown from a subroutine).

EDIT: Gray Wolf beat me to it!
Last edited on
I feel sorry for you Duoas, having to correct everyone an all.

Also, useful thread, I had the same problem.
Eh heh, don't feel bad. There's a good laugh factor in here.

The reason I make such a fuss is since I've become active in online forums I've realized that people really don't know that system("PAUSE") and like constructs are actually a Bad Thing.

They're fine for just dinking around on your own or for some cheesy homework solution, but they should never find themselves into production code.

At some point people need to learn how to do it the Right Way. Might as well be sooner than later.

;-)
Last edited on
@Duoas:
The related one is the "cls" (or "clear" in Unix/Linux). The problem with that one is that it encourages people to use it trivially, when it is in fact an OS-specific (and often terminal-specific) thing to do.


While I only use it in school right now, I use system("cls") and system("pause") extensively in my programs. I read about your alternative and rest assured I will be adding that to my toolbox, however I am really curious about what the alternative to system("cls") would be?

Thanks
Az
That gets asked a lot.

The alternative is: "Don't use it."

There are very, very good reasons for this that most programmers are afraid to know simply because they fall under the heading of "UI". In the simplest terms I can put it, unless your program will only work when talking directly to a human (like a word processor or a game), don't mess with the console. When you do, you reduce the options available to the user with your program.


Hope this helps.
Hi I have 2 questions!!!!!!!!!!111

FIRST QUESTION: in many forums I have visited about C++ everyone when showing a part of their program writes:

1
2
std::cout << "Press ENTER to continue...";
std::cin.ignore( std::numeric_limits<std::streamsize>::max(), '\n' );


Why do they write that STD:: BEFORE each line? If i copy it and paste it into Dev C++ I always have to remove the STD:: otherwise it does not work properly.


SECOND QUESTION:

In order to PAUSE the command prompt you recommend to use

1
2
3
4
5
  std::cout << "Press ENTER to continue...";
  std::cin.ignore( std::numeric_limits<std::streamsize>::max(), '\n' );

  return 0;
  }


Can someone explain what EACH value means for example what am I suppose to put in "numeric_limits," "streamsize," and "max()" ???



THANK YOU!
Sure.

1) Things like cout and streamsize and the like are in the std namespace. You can only access them if you qualify their full name. There are two ways to do this.

a) Tell the compiler you plan to use stuff (or something particular) in the std namespace.
1
2
3
4
5
using namespace std;  // Don't bug me about the full names of anything in the std namespace

//or

using std::cout;  // Don't bug me about cout's full name when I just say 'cout'. 

Now you can say:
 
cout << "Hello world!"; // the compiler knows that I mean std::cout 


b) Use its full name.
 
std::cout << "Hello world!";


If Dev-C++ is complaining when you use the full name of something, then there is something wrong with the way it is set-up.


2) cin.ignore()
http://www.cplusplus.com/reference/iostream/istream/ignore.html

numeric_limits
http://msdn.microsoft.com/en-us/library/yefe7a47(VS.80).aspx
Describes things about basic data types, like streamsize

So basically what it is saying is "ignore all the characters you get from cin until you find '\n' or you read as many characters as a stream can hold."

Hope this helps.
Thanks I get the first answer well :D

one question for the cin.ignore, why do people put cin.ignore (80,'\n'); what makes them pick 80 or anything for that number. Why not just put 1 or 2. What makes them think of putting 80? Thanks Again!
Laziness, I suppose? It depends on the program.
hmm I do not think im understanding :(

Ok in terms of

cin.ignore( numeric_limits<streamsize>::max(), '\n' );

in cin.ignore(80,'\n');

the 80 = numeric_limits<streamsize>::max()

right?

so the program will extract 80 characters after the last input, unless it sees a whitespace then it will stop right there. BUT how does that make the program "pause." After extracting the appropriate number of characters shouldn't it just close like it was doing without the cin.ignore.


I think what im thinking is that the cin.ignore should take the input that is left over from previous "cin.get," but maybe that is not what it is doing. Instead does it pause because it is waiting for the user to give the next input and after a NEW INPUT is given by the user it will stop/close the console?
Thanks!
Last edited on
80 != numeric_limits<streamsize>::max()

If an input stream were only limited t|o eighty characters we'd have really short programs. The pipe (|) in the previous sentence is where my answer would have ended with an eighty character limit, just so you get a sense of how small that is.

The purpose of the cin.ignore() is to wait for the user to press the ENTER key again, hence the prompt "Press ENTER to continue...".

So, imagine this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
int main()
  {
  // Be Eliza
  string s;
  cout << "What is your favorite color? ";
  cin >> s;
  cout << "Why do you like " << s << " so much?\n";

  // gobble the ENTER from the last >>
  cin.get();

  // Program's over. Wait for user to press some input.
  cout << "Press ENTER to quit.";
  cin.get();
  //or
  cin.ignore( 1, '\n' );
  //or
  getchar();
  // or whatever

  cout << "bye.";
  return 0;
  }

Now the program runs like this:
What is your favorite color?

Program waits for user to enter input
What is your favorite color? dark green

User types "dark green" and presses enter
What is your favorite color? dark green
Why do you like dark so much?
Press ENTER to quit
bye.

Program reads "dark" and goofs on " green", and terminates too soon.

That extra " green\n" left in the buffer caused line 10 to pass without eating an ENTER (it ate a space instead), and then line 14 or 16 or whatever to pass without eating an ENTER (it eats a 'g' instead).

By ignoring everything up to and including a newline, you guarantee that no matter what nonsense the user typed in, the program doesn't become confused about the state of the input stream.

Let's revise our program
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
int main()
  {
  // Be Eliza
  string s;
  cout << "What is your favorite color? ";
  cin >> s;
  cout << "Why do you like " << s << " so much?\n";

  // gobble everything until the ENTER from the last >>
  cin.ignore( numeric_limits<streamsize>, '\n' );
  // ASSERTED: we know that the input stream is at the beginning of the next line

  // Program's over. Wait for user to press -anything-, up to and including the ENTER key
  cout << "Press ENTER to quit.";
  cin.ignore( numeric_limits<streamsize>, '\n' );
  // ASSERTED: we know the user had to press at least the ENTER key to get this far.

  cout << "bye.";
  return 0;
  }


Now we run the program and it behaves correctly:
What is your favorite color?

Program waits for user input.
What is your favorite color? dark green

User types "dark green" and presses ENTER.
What is your favorite color? dark green
Why do you like dark so much?
Press ENTER to quit

Program still reads just "dark", but correctly ignores " green" and now waits for more input. User presses ENTER.
What is your favorite color? dark green
Why do you like dark so much?
Press ENTER to quit
bye.

Having pressed ENTER, program is satisfied and program quits.

The user even had a chance to type in nonsense when asked just to press ENTER, and it would still work correctly.

Hope this helps.
@Duoas

Thanks for wonderful explanation.
If you use windows, just in the cmd envirement (instead of double click in the windows envirement) to run the .exe file.

Then you can see the result.
That's the way I always tend to do it. But most people I think like to have the IDE do it for them. It is too bad that most IDEs are too dumb to keep the window open for them though...

I was certain Windows had an option to keep console windows open, but I can't find it off the top of my head... If I do I'll post back.
In Visual C++ Express Edition you can use the "Start Without Debugging" that holds the console window open at the end. But you are loosing the debugging options, if you use them.
For debugging, you could just put a breakpoint on the return from main.
I have never used system("pause") before but instad used some of the "standard" code shown above because I found it to e need solutions.
To make the program pause for a given time without interaction from the user, I used the GetTickCount() function together with a while-loop. This has, so far, been adequate for all my little assignment-softwares.

But how do I clear the screen without system("cls")?

regards

int main
Well, int, if you use a borland compiler, I think there is a function called clr.src() or summat.

Correct me if I'm wrong.

QWERTYman
Defender against the DVORAK horde
The short answer is: don't.

And the simple answer is: cout << string( 100, '\n' );

Things like PAUSE and CLS are antithetical to stream applications (or "console applications") because they violate a fundamental given:

- The standard input and output may not necessarily be attached to a terminal. -


There is some history to this. Before Unix and C came along, the poor saps programming on computer systems had to know how to connect with the desired I/O devices --which was often not a simple task, as each piece of hardware needed to be treated differently just to do something like, say, read a single character --or whatever you could get from the device. This made programs specific to particular pieces of hardware and often involved some complicated job setup scripts.

Unix (and consequently, C) introduced a groundbreaking concept that we take for granted today: I/O streams are decoupled from any specific device (meaning that you can read and write characters and the OS handles all the underlying translations to and/or from specific devices) and they are automatically opened when the program starts (meaning that the programmer doesn't have to know any particular magic to open them).

This abstraction also provided a powerful capability copied by nearly every major OS since: I/O redirection.


- Applications Shouldn't Control the User -

So, putting a PAUSE or CLS in there kind of throws a wrench in all that. It means: "I don't care how you want to control my program -- I demand that there be a human sitting in front of a terminal to run it."


Now, when you are writing and running the program yourself, you already know that there is a human sitting in front of a terminal (yourself). So it is fine to stick a system("PAUSE") in there so you can see it work properly. But once it is time to send it off to your professor or put it out on the internet or whatever, those kinds of demand constraints need to go, for the reasons above and also for those previously mentioned (including the fact that using system() is a positive security breach).

If I were teaching a C or C++ programming course, the very first day of class I would make it clear that anyone turning in homework with system() calls to things like PAUSE would loose grade points.


- Acceptable Exceptions -

There are, of course, times when a program should require a human (such as a fullscreen text editor), or at least recognize when one is present. A very good article that covers all the important points is
fileno(3) on C++ Streams: A Hacker's Lament
http://www.ginac.de/~kreckel/fileno/

In the case that you actually do need to manipulate the terminal directly, you should do so explicitly by using console-specific functions. I recommend the Curses library, which works very well on a lot of platforms.
PDCurses Windows, DOS, OS/2...
http://pdcurses.sourceforge.net/

NCurses POSIX platforms (Unix, Linux, OS X...)
http://www.gnu.org/software/ncurses/

Both are highly compatible, and code written for one should work identically for the other. On most Linux systems, and many Unices, ncurses is already installed for you. Failing that apt-get will install it for you.


Outside of a nice library like Curses, you must go straight to the OS to do things like clear the screen.

Performing a Clear Screen (CLS) in a Console Application
http://support.microsoft.com/kb/99261

Again, for POSIX platforms, if you have terminfo installed you also have curses installed. If you are on something really ancient that only has termcap it is still worth your while to install ncurses because it will work with whichever of the two terminal databases it finds.


Whew. Hope this helps.
Last edited on
Pages: 1234... 7