Good Morning,

This is a bit of a double question thread. First what i have done is written a basic stop watch program, it runs through the loops and iterates the time on screen.
My first question is this: is there some way to leave the program listening for user input to stop or reset the time or to exit the program?

Secondly i used the system("CLS") to clear the previous count every time, i am under the understanding that this is not portable and not a good way to get the desired result. Is there some other way to have the cout of time to overwrite the last cout?


here is my code:

#include <iostream>
#include <cstdlib>
#include <windows.h>


using namespace std;

void stop_watch();

int main() {
    stop_watch();
    cin.get();
    return 0;
}

void stop_watch() {
     int hour = 0, min = 0, sec =0;
     
     for (hour = 0; hour <= 1; hour++){
         for (min = 0; min < 61; min++){
             for (sec = 0; sec < 61; sec++){
                 Sleep(1000);
                 system("CLS");
                 cout << hour << ":" << min << ":" <<sec;
                 }
             }
         }
}

The system("CLS") isn't a huge deal as it works for my situation right now, however in the spirit of doing things properly i would love to hear peoples ideas on this.

thanks

Recommended Answers

All 14 Replies

For the second question you could use \r in a print statement. This goes to the start of the line on the console window. So suppose I had this:

std::cout << "hello, \rworld";

I would get out:

"world, "

Least I think it's \r Only danger with it though is that you have to be certain that what you're writing is longer or the same length as what's there. It's like writing with the insert thing off so it writes over what's in your screen.
Also, if you want to clear the screen totally you can use the last option here -- http://faq.cprogramming.com/cgi-bin/smartfaq.cgi?answer=1031963460&id=1043284385 Just add the function and call it whenever you want to do the clearin'.

>> is there some way to leave the program listening for user input to stop or reset the time or to exit the program?
Listening for user input... you could use getch() (conio.h, but it's not portable), kbhit() (conio again, I think, either that or windows), or a combination of both:

char ch;
while( !kbhit() ) {
  ch = getch();
  // do something with the timer
  std::cout<< "You hit: " << ch << "\n";
}

For the second question you could use \r in a print statement. This goes to the start of the line on the console window. So suppose I had this:

std::cout << "hello, \rworld";

I would get out:

"world, "

Least I think it's \r

twomers, the \r works perfectly, also probably a bit more portable that the system("cls").
is there some where i can find out about the diferent \'s? i know \n and \r now, what other ones are there?

I am also working on the user input problem, will update every one once i figure something out.

thanks

is there some where i can find out about the diferent \'s? i know \n and \r now, what other ones are there?

here

>>I am also working on the user input problem, will update every one once i figure something
I would create another thread and put the timer in that thread then you can use normal standard input functions in the primary thread.

Ancient Dragon Thanks for the page on escape sequences, i wasn't even sure what to call then.

I think multiple threads is a bit beyond my experience, I understand the concept just not how to implement it, any pointers on that?

thanks again!

There are several ways to create threads, depending on the operating system. MS-Windows can use CreteThread() win32 api function, or _beginthread(). I've always used CreateThread() in my windows programs. Its not really all that difficult and you should be able to use google and find lots of examples.

Awesome, Thanks!
I will look into that as well, thank you

> I think multiple threads is a bit beyond my experience...
it would be easier to use a console input buffer and wait for it to be signalled.

#include <iostream>
#include <iomanip>
#include <windows.h>
using namespace std ;

int main()
{
    HANDLE input = CreateFileA( "CONIN$", 
                    GENERIC_READ|GENERIC_WRITE, 0, 0, 
                    OPEN_EXISTING, FILE_FLAG_OVERLAPPED, 0 ) ;
    FlushConsoleInputBuffer(input) ;

    for ( int hour = 0; hour < 2 ; ++hour )
         for (int min = 0; min < 60 ; ++min )
             for ( int sec = 0; sec < 60 ; ++sec )
                 if( WaitForSingleObject( input, 1000 ) 
                        == WAIT_TIMEOUT )
                     cout << '\r' << hour << ':' << setw(2) 
                       << setfill('0') << min << ':' << setw(2) 
                       << setfill('0') << sec << flush ;
}

If you wish this to be "portable" across at least Windows and Unix, you should make use of the curses library. You can get PDCurses which works on both systems, and a few others to boot. Most *nix systems come with ncurses (or at least curses) already installed and usable. (Most basic curses functions are common to all three packages.)

Using curses allows you to directly control device input. You can test for input (whether there is any to read or not) and do fancy output, all using a library that is very portable.

Else:

To create a new thread in windows, all you really need is a function that will be called in the new thread. So your program will have a main() function, which gets executed when your program runs normally, and another function which is like main() but for that thread. You will also have to look up how to send signals between the threads, because you can't just modify common data without the possibility of corrupting it. The only exception would be if only one thread can write to a single-byte variable (such a boolean), and the other(s) may only read it. Not the best answer, but the simplest.

There is nothing wrong with using a system program to clear the screen. It is simple and you can count on "cls" or "clear" being present on most systems. The drawback is, of course, that it is a foreign program. See here for more.

Both \r and \b are almost guaranteed to work on any tty device.

> If you wish this to be "portable" across at least Windows and Unix, you should make use of the curses library.
if the definition of 'user input' is limited to characters typed in on the keyboard (except things like ALT+TAB) while the console/terminal has input focus, curses is a portable option. if 'user input' has a more general meaning, it would include input via menu, mouse, focus etc. i think it would be possible to write a library that would work in both windows and unix for these, but i do not know if such a library has been written.

There is nothing wrong with using a system program to clear the screen. It is simple and you can count on "cls" or "clear" being present on most systems.

Totally disagree.
#1) Which is it going to be? And how do you write portability with multiple choices like this?
#2) I somewhat doubt most systems have them. Windows may have cls and most *nix I guess have clear, but these are far from being most systems.

vijayan121
> it would include input via menu, mouse, focus etc.
Please see the curses library to do those things.

WaltP
1. See the link I posted.
2. How many CLI systems do you know of these days that are in common use by the hoi polloi? Anyone writing secure systems or for something old or unusual won't post here asking how to clear the screen cross-platform.

WaltP
1. See the link I posted.

I did. Try one then the other is not a portable solution.

2. How many CLI systems do you know of these days that are in common use by the hoi polloi? Anyone writing secure systems or for something old or unusual won't post here asking how to clear the screen cross-platform.

Lots. With this list of O/S's "you can count on "cls" or "clear" being present on most systems" a invalid statement. Granted, not all the systems listed are in use today, but more than Windows, *nix, and OS/X have been posted here.

And, since I keep getting blasted for being just ever so slightly off when I make a statement like yours, then we all better be more exact. I no longer make a blanket statement that has 'grey areas' if you go back far enough or get specialized enough. Sorry.

Anyway, no matter how you slice it, "you can count on "cls" or "clear" being present on most systems" is simply bad advice.

> it would include input via menu, mouse, focus etc.
>> please see the curses library to do those things.

ncurses has minimal support for mouse, none at all for focus/console window menu.

The ncurses library also provides a mouse interface. Note: his facility is original to ncurses, it is not part of either the XSI Curses standard, nor of System V Release 4, nor BSD curses. Thus, we recommend that you wrap mouse-related code in an #ifdef using the feature macro NCURSES_MOUSE_VERSION

from 'Writing Programs with ncurses' by Eric S. Raymond and Zeyd M. Ben-Halim

Portability
These calls were designed for ncurses(3X), and are not found in SVr4 curses, 4.4BSD curses, or any other previous version of curses.
The feature macro NCURSES_MOUSE_VERSION is provided so the preprocessor can be used to test whether these features are present .... Under ncurses(3X), these calls are implemented using either xterm's built-in mouse-tracking API or platform-specific drivers including Alessandro Rubini's gpm server, FreeBSD ysmouse, OS/2 EMX
If you are using an unsupported configuration, mouse events will not be visible to ncurses(3X) (and the wmousemask function will always return 0).

linux man page for ncurses

if you have a snippet where just mouse handling (forget console menu and focus) can be done using curses (portably), please post it; i would have learned something new.

> Try one then the other is not a portable solution.
How so? It works on both systems! (It most certainly is a cheap kludge! That's not the point. The point is that it works.)

Your list of OSes is considerably short. You are absolutely right: my wording was off and I've not expressed myself clearly. I mean that most of the people posting here are using systems that it would work on. Those that aren't know better, because of the very fact that it isn't Windows or some Unix derivative. I will try to be more explicit in the future.

vijayan121
Wait... you mean you want to write a console program that knows how to interact with other programs in a GUI system? Good luck with that.

If you want to use the mouse and create text menus and other windows within your console application then that is quite frankly what curses was designed for. Go read the docs again. You'll recall that console programs aren't designed to have any clue about each other. That's traditionally been the OS's job. You can't give me a hard time because your console program doesn't know how to respond like a windows program.

Using the mouse is always a system-specific thing. Just like using the flaming keyboard and display. Hence the purpose of libraries like curses. I know PDCurses works well and that it covers nearly every platform curses and ncurses does (plus some they don't). I'm sure if you find an old enough version you'll miss some functionality...

I never said there was one perfect, end-all solution for every stinking system out there. I did say that if you want portability on a console, you won't find a better library than curses. ESR has devoted a large chunk of his life to making that so.

As a final note (I don't feel like getting beat on any more by those who should know better only for simple, audience-generalized advice.) There is no such thing as a programming system that is so portable that you don't have to personally account for your target system in some way. Even perfectly portable, C++ standard code must be compiled and linked as per your target. It can't do it for you. Why would Boost people write bjam instead of just using autoconf and configure? Why do you still have to configure bjam how to do its job? The curses library is no different. If you want to use the mouse you'll have to configure it correctly for your system. And it won't work on every system.

Them's the breaks and it ain't my fault. If that still really bugs you go yell at ESR and leave me alone!

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.