MAGIC PAUSE BLOCK

So much grief over system("PAUSE").
There is, of course, Narue's brilliant post here:
https://www.daniweb.com/software-development/cpp/threads/90228/flushing-the-input-stream

But no one reads nothing. So...

Stick this somewhere in your program

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#ifdef _WIN32
  // Magic PAUSE block. I found it on the internet at:
  // http://www.cplusplus.com/
  #include <iostream>
  #include <string>
  #ifndef NOMINMAX
  #define NOMINMAX
  #endif
  #include <windows.h>
  struct pause_on_quit { bool is_console_owner; pause_on_quit() { 
  FreeConsole(); is_console_owner = !AttachConsole( ATTACH_PARENT_PROCESS );
  if (is_console_owner) AllocConsole(); } ~pause_on_quit() { if 
  (is_console_owner) { std::cout << "All done. Press ENTER or close the "
  "window."; FlushConsoleInputBuffer( GetStdHandle( STD_INPUT_HANDLE ) ); 
  std::string s; std::getline( std::cin, s ); } } } Z201508081318;
#endif 

It doesn't really matter where, as long as you don't stick it in the middle of a function or something. I would just cut and paste it to the last line of your .cpp file. (And, only include it in the file that has main().)

Tada!


Something prettier
To make it do things with pretty colors, you need to make it bigger. For that, here's a .hpp file you can #include.

    pause_on_quit.hpp
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
71
72
73
// pause_on_quit.hpp
//
// Keeps the console open until you close it, but only if necessary.
//
// Released to the Public Domain.
// -- Michael Thomas Greer

#pragma once
#ifndef DUTHOMHAS_PAUSE_ON_QUIT_HPP
#define DUTHOMHAS_PAUSE_ON_QUIT_HPP

#ifdef _WIN32

  #include <iostream>
  #include <string>

  #ifndef NOMINMAX
  #define NOMINMAX
  #endif
  #include <windows.h>
  
  struct pause_on_quit
  {
    bool is_console_owner;
    
    pause_on_quit()
    {
      // This works by trying to attach to the parent's console.
      // If Windows had to create a console for my program, then
      // there won't be a parent console to attach to.
      FreeConsole();
      is_console_owner = !AttachConsole( ATTACH_PARENT_PROCESS );
      if (is_console_owner) AllocConsole();
    }
    
   ~pause_on_quit()
    {
      if (is_console_owner)
      {
        // Let the user know that the program is done
        #ifndef NO_PRETTY_PAUSE_ON_QUIT
        std::cout << std::flush;
      
        CONSOLE_SCREEN_BUFFER_INFO csbi;
        HANDLE hStdOut = GetStdHandle( STD_OUTPUT_HANDLE );
        GetConsoleScreenBufferInfo( hStdOut, &csbi );
        DWORD color = ((csbi.wAttributes & 0xF0) != 0x30) ? 0x3E : 0x4E;
        SetConsoleTextAttribute( hStdOut, color );
        
        COORD coords = { csbi.srWindow.Left, csbi.srWindow.Bottom };
        DWORD ncells = csbi.srWindow.Right - csbi.srWindow.Left + 1;
        DWORD nfooey;
        FillConsoleOutputCharacterA( hStdOut, ' ',   ncells, coords, &nfooey );
        FillConsoleOutputAttribute(  hStdOut, color, ncells, coords, &nfooey );
        SetConsoleCursorPosition( hStdOut, coords );
        SetConsoleTitle( "Press ENTER or close the window." );
        #endif
        std::cout << "Press ENTER or close the window.";
        
        // Hang around until the user closes the console window.
        FlushConsoleInputBuffer( GetStdHandle( STD_INPUT_HANDLE ) );
        std::string s;
        std::getline( std::cin, s );
      }
    }
  } 
  Z201508081318;
  
#endif

#endif

// end pause_on_quit.hpp 

Just stick that file in the same directory as your .cpp file. Here's a complete example program:

1
2
3
4
5
6
7
8
9
#include <iostream>
#include "pause_on_quit.hpp"
using namespace std;

int main( int argc, char** argv )
{
  for (int n = 0; n < argc; n++)
    cout << n << ": " << argv[n] << "\n";
}


Advantages
The whole point of this is to mitigate streams applications and the "how do I keep the console window open" problem.

    - If you run the program from the console window, it will just quit,
      without asking you to press Enter or anything.

    - If you start it where I/O is redirected in any way, it'll just quit.

    - But if you run the program by double-clicking on it in Windows Explorer,
      it'll keep the window open for you when your program is done.


Disadvantage
It only works on Windows.

If I get some demand to make it work on Linux too (before this thread archives), I'll update it.


Enjoy!
Last edited on
Did I sleep through August to April 1st?
Maybe. :O]

Seriously, though, this is a better solution than cin >> x and system("PAUSE") because it Does The Right Thing.
¿why the lack of indentation on the first snip?


> ~pause_on_quit()
http://stackoverflow.com/questions/222175/why-destructor-is-not-called-on-exception
So it doesn't solve the "keep console open" problem

Another thing (that I cannot test:)
Suppose that all the input was already consumed (or that the program did not ask any input), then it comes a lenghty proccess after which the pause() would execute.
¿what if the user presses Enter during the lenghty process?
The first snippet is meant to be small and unobtrusive, if not ugly.

Re: abnormal terminations.
Crap. Forgot about that. I'll have to fix that.

Re: press enter in lengthy process:
It uses Windows Console functions to explicitly not-care about any previous input. But the exit handler is only called when globals go out of scope on program shutdown. All lengthy processes are done. (If user has a lengthy shutdown process tied to global variable scope, I cannot control that dumbness.)


[edit] I remember now why I didn't bother.
If your program terminates abnormally, the window will not close until you click the little popup dialog about finding a solution to the problem. During that time you still have access to the Console Window -- you can even scroll about and select text.
Last edited on
¿what if the user presses Enter during the lenghty process?
In theory it would be discarded by flushing input buffer.


So it doesn't solve the "keep console open" problem
Also it might not show messages printed in static objects destructors. And it doesn't pause if program is abnormally terminated for any reason.

And incidentally same poblem occurs with other solutions. This is just better than others.
It is fine enough to propose it as "paste and forget" solution for those who isn't able to configure their IDE or run through command line.

EDIT: ninja'd :)
Last edited on
Topic archived. No new replies allowed.