Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Cross Platform clear terminal

216 views
Skip to first unread message

Glen Barber

unread,
Jan 23, 2008, 7:15:05 AM1/23/08
to
Hello folks.

I've been reading a few C++ books, trying to teach myself as much about the
language as I can. So far, so good, until I encountered my first
cross-platform problem.

I've been doing my developing in FreeBSD, and testing the portability in
Win32 using the Bloodshed Dev-C++ IDE and MinGW compiler.

What I intended (and it works in UNIX) is, before anything else, to clear
the console. For this, I used:
system("clear");
however, I have read this is a "crude hack".

It does, for the intent of my test app, compile and execute as expected; but
in Win32, obviously "clear" isn't a command -- "cls" is.

Before I create a monster of hacked code that will be impossible to "fix", I
figured I'd ask here.

I am aware I need the application to differentiate between what platform it
is running, but I can't seem to figure out (or find via Google) what I
might be missing. Any pointers would be greatly appreciated.

Thanks in advance.

--
Glen Barber

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Ulrich Eckhardt

unread,
Jan 23, 2008, 9:27:27 PM1/23/08
to
Glen Barber wrote:
> What I intended (and it works in UNIX) is, before anything else, to clear
> the console. For this, I used:
> system("clear");
> however, I have read this is a "crude hack".

This creates a shell and executes 'clear' in that shell's context. Whether
this 'clear' makes any sense in that shell's context is up to the shell and
possibly the installed programs. It might as well clear your harddisk or
make the window translucent, as far as C++ is concerned.

> It does, for the intent of my test app, compile and execute as expected;
> but in Win32, obviously "clear" isn't a command -- "cls" is.

Well, the mechanism is the same but as already mentioned, the shell is a
different one thus the different command or program needed.

What you can do is define the argument to system() via an environment
variable or configuration option. If it doesn't exist you fall back to
doing nothing. That allows you to customise the behaviour of your program
to the used shell without recompiling the program itself, while still
hopefully getting readable output without it.

> I am aware I need the application to differentiate between what platform
> it is running, but I can't seem to figure out (or find via Google) what I
> might be missing. Any pointers would be greatly appreciated.

There is no universal way to do what you want. E.g. if you attach the
program to a line printer, you simply can't erase lines already written.
What you can do is print a few newlines to make a visual separation to the
current content, this is also portable. For anything further, you need
add-on libraries that allow you to control a terminal.

The typically-used interface for terminal control is called 'curses', which
comes in different implementations for most desktop OSs. This then also
allows you to do things like positioning the cursor or create ASCII-art
windows like e.g. Norton Commander does. However, even though this API has
been widely ported, it still relies on features that are not guaranteed to
be present and thus are not 100% portable.

Uli

--
Sator Laser GmbH
Geschäftsführer: Michael Wöhrmann, Amtsgericht Hamburg HR B62 932

ap...@student.open.ac.uk

unread,
Jan 23, 2008, 9:31:06 PM1/23/08
to
On 23 Jan, 12:15, Glen Barber <hexidigi...@gmail.com> wrote:
> What I intended (and it works in UNIX) is, before anything else, to clear
> the console. For this, I used:
> system("clear");

Not only does this presume UNIX, it presumes there is a screen to
clear. That is not true for all apps. Suppose you are writing a server
that sits there as a background or daemon process. If written properly
there will be no console or screen associated with that process.

> however, I have read this is a "crude hack".

Yes it is. In UNIX tty-style screen manipulation is done using curses.
The GNU version of the curses library is a very good implementation of
it IMHO.

> It does, for the intent of my test app, compile and execute as expected; but
> in Win32, obviously "clear" isn't a command -- "cls" is.

Again, the same considerations apply, the app is assuming that there
is a screen there to clear. If this assumption is valid then using
curses will not help you on Windoze unless you are using cygwin. So it
seems to me like you have to use an ifdef somewhere. So if you want a
crude hack how about:

#ifdef _WIN32
system("cls");
#else
system("clear");
#endif

> Before I create a monster of hacked code that will be impossible to "fix", I
> figured I'd ask here.
>
> I am aware I need the application to differentiate between what platform it
> is running, but I can't seem to figure out (or find via Google) what I
> might be missing. Any pointers would be greatly appreciated.

One of the many troubles with ifdefs is once you start with one, it
rarely ends there. And even if it does, that ifdef is destined to grow
to cover more cases. For example, my hack above will not work for 64
bit Windoze. And it assumes if you are not Windoze then you must be
Unix so it will fail on VMS. I think on VMS there is yet another way
of clearing the screen. Curses is available for VMS though.

> Thanks in advance.
>
> --
> Glen Barber

Regards,

Andrew Marlow

--

R.F. Pels

unread,
Jan 23, 2008, 9:42:57 PM1/23/08
to
Glen Barber wrote:

> What I intended (and it works in UNIX) is, before anything else, to clear
> the console.

... destroying what was displayed in the first place. Shoo. You should by
now realize that doing that is rude, unless you can restore the console
output to what it has been after exiting your program. For that matter,
consult the source of for example the program 'less'...

Now, to do this stuff you might consider using curses.

--
Ruurd

Alex

unread,
Jan 25, 2008, 10:45:48 AM1/25/08
to
On Jan 23, 7:15 am, Glen Barber <hexidigi...@gmail.com> wrote:

> Before I create a monster of hacked code that will be impossible to "fix", I
> figured I'd ask here.
>
> I am aware I need the application to differentiate between what platform it
> is running, but I can't seem to figure out (or find via Google) what I
> might be missing. Any pointers would be greatly appreciated.

You have to compile different versions of your program, depending on
the target platform, like this:

#if defined(__FreeBSD__)
system("clear");
#elif defined(MINGW)
system("cls");
#endif

In complex scenarios, coding like this can quickly become an
unmaintainable mess, so you may want to come up with a more
sophisticated way to do it (e.g. put platform dependent code in
separate files and conditionally include them).

HTH

Alex

--

int...@gmail.com

unread,
Jan 25, 2008, 10:45:25 AM1/25/08
to
On Jan 23, 3:15 pm, Glen Barber <hexidigi...@gmail.com> wrote:

> I've been reading a few C++ books, trying to teach myself as much
> about the
> language as I can. So far, so good, until I encountered my first
> cross-platform problem.
>
> I've been doing my developing in FreeBSD, and testing the
> portability in
> Win32 using the Bloodshed Dev-C++ IDE and MinGW compiler.
>
> What I intended (and it works in UNIX) is, before anything else, to
> clear
> the console. For this, I used:
> system("clear");
> however, I have read this is a "crude hack".
>
> It does, for the intent of my test app, compile and execute as
> expected; but
> in Win32, obviously "clear" isn't a command -- "cls" is.
>
> Before I create a monster of hacked code that will be impossible to
> "fix", I
> figured I'd ask here.
>
> I am aware I need the application to differentiate between what
> platform it
> is running, but I can't seem to figure out (or find via Google) what I
> might be missing. Any pointers would be greatly appreciated.
>
> Thanks in advance.

As long as we're speaking of standard C++, a "terminal" (i.e. your
standard output) might not even be something you can clear - even on
Win32 or *nix-like, it can be redirected to a file, and what if it's a
printer? If you actually need to work with a screen, which can be
cleared, and where cursor can be repositioned, and you want your code
to remain as cross-platform as possible, you should use something like
ncurses (http://www.gnu.org/software/ncurses/ncurses.html).


--

Glen Barber

unread,
Jan 25, 2008, 10:45:40 AM1/25/08
to
ap...@student.open.ac.uk wrote:

>
> #ifdef _WIN32
> system("cls");
> #else
> system("clear");
> #endif
>

Besides 'curses', this seems to be at least something I can work with to do
cross-platform (at least on Win32 and UNIX).

>
> One of the many troubles with ifdefs is once you start with one, it
> rarely ends there. And even if it does, that ifdef is destined to grow
> to cover more cases. For example, my hack above will not work for 64
> bit Windoze. And it assumes if you are not Windoze then you must be
> Unix so it will fail on VMS. I think on VMS there is yet another way
> of clearing the screen. Curses is available for VMS though.

I'll definitely keep this in mind as I gain more experience. I appreciate
your input.

--
Glen Barber

Glen Barber

unread,
Jan 25, 2008, 10:45:41 AM1/25/08
to
Ulrich Eckhardt wrote:

>
> This creates a shell and executes 'clear' in that shell's context. Whether
> this 'clear' makes any sense in that shell's context is up to the shell
> and possibly the installed programs. It might as well clear your harddisk
> or make the window translucent, as far as C++ is concerned.
>

Yes, I am aware anything in 'system()' will execute a system command.

>
> The typically-used interface for terminal control is called 'curses',
> which comes in different implementations for most desktop OSs. This then
> also allows you to do things like positioning the cursor or create
> ASCII-art windows like e.g. Norton Commander does. However, even though
> this API has been widely ported, it still relies on features that are not
> guaranteed to be present and thus are not 100% portable.
>

You're the third person to mention 'curses'. :) Seems it will have to be
something I will be looking into soon.

Thanks for your input. I appreciate it!

--
Glen Barber

ap...@student.open.ac.uk

unread,
Jan 25, 2008, 10:45:54 AM1/25/08
to
On 24 Jan, 02:42, "R.F. Pels" <ru...@tiscali.nl> wrote:
> Glen Barber wrote:
> > What I intended (and it works in UNIX) is, before anything else, to clear
> > the console.
>
> ... destroying what was displayed in the first place. Shoo. You should by
> now realize that doing that is rude, unless you can restore the console
> output to what it has been after exiting your program. For that matter,
> consult the source of for example the program 'less'...
>
> Now, to do this stuff you might consider using curses.

Indeed. And I have just found out that there is a version of curses
for Windoze as well. See http://pdcurses.sourceforge.net for details.

Regards,

Andrew Marlow

--

Bart van Ingen Schenau

unread,
Jan 25, 2008, 10:45:40 AM1/25/08
to
Glen Barber wrote:

> Hello folks.
>
> I've been reading a few C++ books, trying to teach myself as much
> about the
> language as I can. So far, so good, until I encountered my first
> cross-platform problem.
>
> I've been doing my developing in FreeBSD, and testing the portability
> in Win32 using the Bloodshed Dev-C++ IDE and MinGW compiler.
>
> What I intended (and it works in UNIX) is, before anything else, to
> clear
> the console. For this, I used:
> system("clear");
> however, I have read this is a "crude hack".

A number of people, including me, seriously hate it when an application
needlessly clears the console.
I would therefor ask you not to do that unless your application is
designed to use the entire console window.

>
> It does, for the intent of my test app, compile and execute as
> expected; but in Win32, obviously "clear" isn't a command -- "cls" is.
>
> Before I create a monster of hacked code that will be impossible to
> "fix", I figured I'd ask here.
>
> I am aware I need the application to differentiate between what
> platform it is running, but I can't seem to figure out (or find via
> Google) what I
> might be missing. Any pointers would be greatly appreciated.

Clearing the console is not defined by the C++ standard, so it is
inherently platform dependent.

There are a couple of common ways to have platform dependent code in an
otherwise platform independent project:

1. Use wrapper functions.
You write a set of wrapper functions that provide a generic interface to
the platform dependent functionality that you want.
Then you provide a set of source files with the implementation for the
wrapper functions. For each supported platform, you provide a different
set of source files.
Using the tools in your build environment, you select the correct set of
source files for the platform that you are building for.

2. Use conditional compilation.
Most compilers will come with a set of predefined macros that, among
other things, identify what platform you are compiling for.
Using #if conditional compilation, you can test these macros and select
the right code for the current platform.

>
> Thanks in advance.
>
Bart v Ingen Schenau
--
a.c.l.l.c-c++ FAQ: http://www.comeaucomputing.com/learn/faq
c.l.c FAQ: http://c-faq.com/
c.l.c++ FAQ: http://www.parashift.com/c++-faq-lite/

mrp

unread,
Jan 25, 2008, 10:45:54 AM1/25/08
to
Refer to this book. Really helpful for doing cross-platform C++
development.

http://www.amazon.com/Cross-Platform-Development-Building-Windows-Applications/dp/032124642X

--

Edward Rosten

unread,
Jan 25, 2008, 12:51:52 PM1/25/08
to
On Jan 23, 5:15 am, Glen Barber <hexidigi...@gmail.com> wrote:

> I've been doing my developing in FreeBSD, and testing the portability in
> Win32 using the Bloodshed Dev-C++ IDE and MinGW compiler.
>
> What I intended (and it works in UNIX) is, before anything else, to clear
> the console. For this, I used:

> I am aware I need the application to differentiate between what platform it


> is running, but I can't seem to figure out (or find via Google) what I
> might be missing. Any pointers would be greatly appreciated.

I'd suggest figuring out which functions you need and then putting
them in a separate file so you can have different functions for
different platforms if need be.

Now, at the risk of getting off topic for clc++m (though this does
come up occasionally)...

you can output ANSI control sequences using standard C++, for instance
in ANSI:

cout << "\x1b[2J\x1b[H" << flush;

will clear the screen and move the cursor to the top left corner. The
vast majority of extant terminal emulators on UNIX platforms
understand ANSI codes. I believe that the Windows command window has a
setting to make it understand ANSI control codes as well.

There's a guide to them here:

http://en.wikipedia.org/wiki/ANSI_escape_code

-Ed
--
(You can't go wrong with psycho-rats.)(http://mi.eng.cam.ac.uk/~er258)

/d{def}def/f{/Times s selectfont}d/s{11}d/r{roll}d f 2/m{moveto}d -1
r 230 350 m 0 1 179{ 1 index show 88 rotate 4 mul 0 rmoveto}for/s 12
d f pop 235 420 translate 0 0 moveto 1 2 scale show showpage


--

0 new messages