-2

I know this question has been asked several times on the net, but I could not find any of those answers helpful.

I want to keep running a loop and break it once the user press a key (e.g. enter or esc). I don't want it to ask user any input during the process.

I have a while loop.

I am new to C++, so please answer simply.

My system is Mac OS X.

CompuChip
  • 9,143
  • 4
  • 24
  • 48
user3720389
  • 27
  • 1
  • 8
  • when run from the command line, the user can press ctrl+C to end a program – FCo Mar 06 '15 at 19:37
  • What have you already tried? – DMP Mar 06 '15 at 19:39
  • 1
    @Crazyman135790: How would that information improve this question? – Benjamin Lindley Mar 06 '15 at 19:39
  • Something like this is OS dependent. – NathanOliver Mar 06 '15 at 19:39
  • @BenjaminLindley any info would help. – DMP Mar 06 '15 at 19:39
  • I think you need more than 1 thead, one to run the loop and second to capture the event and modify a property. You could check the value of property to exit out of loop. – Tachyon Mar 06 '15 at 19:42
  • @Crazyman135790: No, not any info would help. For example, information about what he had for breakfast wouldn't help. And that was not meant to be sarcastic or snarky, just an example of a piece of information that wouldn't improve the question. And I suggest that information about what he tried also lies in that category. – Benjamin Lindley Mar 06 '15 at 19:43
  • Sorry folks. none of your comments does not work for me. – user3720389 Mar 06 '15 at 19:43
  • It doesn't have to be a single operating system or compiler. It can be a set of them. There are libraries that will abstract over the differences. e.g. multimedia libraries like SFML or SDL, or gui libraries like Qt or wxWidgets. Or libraries dedicated specifically to input, like OIS. – Benjamin Lindley Mar 06 '15 at 19:48
  • @Mr.Singh Using threads of C++11 might indeed work in plain C++11... – hyde Mar 06 '15 at 19:49
  • @ user3720389 Do you know how to capture programmatically user's action of pressing key, please share that? – Steephen Mar 06 '15 at 19:49
  • You could use signals to catch a Ctrl-C, or use something non-standard to grab key states in conjunction with threading... – Segmented Mar 06 '15 at 19:53
  • 1
    @hyde I am using Mac OS X, and Xcode. – user3720389 Mar 06 '15 at 19:54
  • @user3720389 Tag your question with that information. – Segmented Mar 06 '15 at 19:55
  • @user3720389 I edited tags. I assumed you are doing a console application. If you in fact have GUI app, please fix the tags! – hyde Mar 06 '15 at 19:57
  • @ hyde thanks. No, I don't have GUI. – user3720389 Mar 06 '15 at 20:01
  • Have a look at the documentation for NSEvent, this might lead you down the right path for grabbing key-states. This is not C++ but Objective-C++ however... Given that you say you are new, maybe take a step back and look for a simpler solution to yield the result you want? – Segmented Mar 06 '15 at 20:01

3 Answers3

2

There you go. I hope this helps.

#include <iostream>
#include <thread>
#include <atomic>

// A flag to indicate whether a key had been pressed.
atomic_bool keyIsPressed(false);

// The function that has the loop.
void loopFunction()
{
    while (!keyIsPressed) {
        // Do whatever
    }
}

// main
int main(int argc, const char * argv[])
{
    // Create a thread for the loop.
    thread loopThread = thread(loopFunction);
    // Wait for user input (single character). This is OS dependent.
#ifdef _WIN32 || _WIN64
    system("pause");
#else
    system("read -n1");
#endif
    // Set the flag with true to break the loop.
    keyIsPressed = true;
    // Wait for the thread to finish.
    loopThread.join();

    // Done.
    return 0;
}

Update: Since the flag keyIsPressed is shared between threads, I added atomic for that. Thanks to @hyde.

user686776
  • 31
  • 3
1

This is indeed OS dependent, but probabilities are that you use Windows.

First, you'll need to include :

#include <Windows.h>

It gives you access to the function GetAsyncKeyState, and to Windows' key macros (list of Windows' key macros).

You'll also need the Most Significant Bit to evaluate key press ; just initialize it as a const in your code :

const unsigned short MSB = 0x8000; 

Finally, let's put all together in a function :

bool listenKeyPress(short p_key)
{
    //if p_key is pushed, the MSB will be set at 1
    if (GetAsyncKeyState(p_key) & MSB)
    {
        return true;
    }

    else return false;
}

//Example of a call to this function to check if up enter is pressed :
listenKeyPress(VK_RETURN)

Then your while loop can be typed either :

while (!listenKeyPress(VK_ENTER))
{
}

or

bool quit = false;
while (!quit)
{
    if (listenKeyPress(VK_ENTER) || listenKeyPress(VK_ESCAPE)
        quit = true;
}

There you go!

0

Was curious myself how to do this when started... turns out never really used it was better to just getch() but if you need this and using windows include Windows.h and the following code should point you in the right direction (hopefully)

bool f = true;
    while (f)
    {
        if (GetAsyncKeyState(VK_UP)){
            //Enter code for when a button is pushed here
            f = false;
        }
        else{
            //Code to run until the button is pushed
        }
    }

If you want to use a different button VK_UP can be changed to any key or mouse button you have, just scroll through the list(assuming you are probably a student using visual studio) if you have no list look up what key applies for the button you wish to press.

EDIT: Also if you want it to run forever remove the f = false and it will work while button is pressed and while not pressed to do whatever you like (Not great coding practice to leave no exit of a while loop though so probably best to test for a key being pressed in another while loop to exit)

bilbsy
  • 67
  • 1
  • 10