system("CLS") is too slow

Apr 24, 2013 at 6:42am
First, a preamble; I don't care that System() is unsafe, and I don't want to implement some sort of graphics interface/layers/windows. I just want to use the command line to display some information.

When I call System("CLS") it takes 140ms to execute (I timed it with clock()). Is this normal? It seems like an excessive amount of time. This figure is pretty much identical between release/debug builds in VS2012. Is there some clean alternative I can use?
Apr 24, 2013 at 6:52am
> I don't care that System() is unsafe

std::system() is not inherently unsafe; but it can be used in an unsafe manner.

> When I call System("CLS") it takes 140ms to execute

Windows CreateProcess() is quite expensive; much more expensive than Unix fork()

For a programmatic way to clear the screen, see: http://support.microsoft.com/kb/99261

Apr 24, 2013 at 7:13am
This seems like what I want to do, but when I include that function it just says that pretty much everything is undeclared.

HANDLE, COORD, BOOL, DWORD, etc. are all undefined. Am I supposed to include something?

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
 /* Standard error macro for reporting API errors */ 
 #define PERR(bSuccess, api){if(!(bSuccess)) printf("%s:Error %d from %s on line %d\n", __FILE__, GetLastError(), api, __LINE__);}

 void cls( HANDLE hConsole )
 {
    COORD coordScreen = { 0, 0 };    /* here's where we'll home the
                                        cursor */ 
    BOOL bSuccess;
    DWORD cCharsWritten;
    CONSOLE_SCREEN_BUFFER_INFO csbi; /* to get buffer info */ 
    DWORD dwConSize;                 /* number of character cells in
                                        the current buffer */ 

    /* get the number of character cells in the current buffer */ 

    bSuccess = GetConsoleScreenBufferInfo( hConsole, &csbi );
    PERR( bSuccess, "GetConsoleScreenBufferInfo" );
    dwConSize = csbi.dwSize.X * csbi.dwSize.Y;

    /* fill the entire screen with blanks */ 

    bSuccess = FillConsoleOutputCharacter( hConsole, (TCHAR) ' ',
       dwConSize, coordScreen, &cCharsWritten );
    PERR( bSuccess, "FillConsoleOutputCharacter" );

    /* get the current text attribute */ 

    bSuccess = GetConsoleScreenBufferInfo( hConsole, &csbi );
    PERR( bSuccess, "ConsoleScreenBufferInfo" );

    /* now set the buffer's attributes accordingly */ 

    bSuccess = FillConsoleOutputAttribute( hConsole, csbi.wAttributes,
       dwConSize, coordScreen, &cCharsWritten );
    PERR( bSuccess, "FillConsoleOutputAttribute" );

    /* put the cursor at (0, 0) */ 

    bSuccess = SetConsoleCursorPosition( hConsole, coordScreen );
    PERR( bSuccess, "SetConsoleCursorPosition" );
    return;
 }


Is this even c++?
Last edited on Apr 24, 2013 at 7:13am
Apr 24, 2013 at 7:32am
1
2
#include <windows.h>
#include <stdio.h> // for ::printf() 


And you may want to declare cls() as

void cls( HANDLE hConsole = ::GetStdHandle(STD_OUTPUT_HANDLE) ) ;

Apr 24, 2013 at 7:36am
I'm getting an explosion of syntax errors as soon as I #include windows.h. Have I corrupted the file or something?

Here's one syntax error that pops up in my main header file (where I make macro declarations):

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
#ifndef __MASTER_H_INCLUDED__
#define __MASTER_H_INCLUDED__
// bunch of #includes
#include <Windows.h>

// Debugging:
#ifdef _DEBUG // if compiler debug mode is on
#define __EDIN_DEBUG // include EDIN-specific variables and checks
#undef NDEBUG // ensure asserts are not suppressed
#else
#define NDEBUG // if _DEBUG is disabled, ensure asserts are suppressed
#endif

#include <assert.h>

//=================================
// Forward declarations
namespace EDIN
{
// bunch of class declarations

	// training classes
	namespace Scheme
	{
		class Fibonacci;
	}

	enum GeneIndex : size_t
	{
		ACT = 0,
		CPY = 1,
		BRN = 2,
	};
	enum Domain : size_t
	{
		IN = 0, // ERROR EXPECTED AN IDENTIFIER
		EX = 1,
	};
// more stuff
}
Apr 24, 2013 at 8:00am
> I'm getting an explosion of syntax errors as soon as I #include windows.h.

There are name clashes with macros defined in <windows.h>

So, insulate the windows stuff in a separate component:

Header cls.h
1
2
3
4
5
6
#ifndef CLS_H_INCLUDED
#define CLS_H_INCLUDED

void cls() ;

#endif // CLS_H_INCLUDED 


Implementation cls.cc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include "cls.h"
#include <windows.h>

void cls()
{
    HANDLE console = ::GetStdHandle(STD_OUTPUT_HANDLE) ;
    CONSOLE_SCREEN_BUFFER_INFO csbi;
    ::GetConsoleScreenBufferInfo( console, &csbi );
    COORD origin = { 0, 0 } ;
    DWORD written ;
    ::FillConsoleOutputCharacterA( console, ' ' , csbi.dwSize.X * csbi.dwSize.Y,
                                   origin, &written );
    ::FillConsoleOutputAttribute( console, csbi.wAttributes, csbi.dwSize.X * csbi.dwSize.Y,
                                  origin, &written );
    ::SetConsoleCursorPosition( console, origin );
}


And then #include "cls.h" in those translation units where you want to call cls();
Apr 24, 2013 at 8:14am
Cool thanks :)
Topic archived. No new replies allowed.