1

I'm using a loop within my main function that looks like this:

while (1)
{
cout << "Hello world" << endl;
}

How would I go about pausing this loop and resume while a key is pressed? For example: When I hold [TAB] down, the loop runs. And when I let go, the loop pauses again.

pnda
  • 135
  • 1
  • 1
  • 11
  • duplicate of "wait for user input" – CashCow Aug 07 '14 at 16:08
  • doesn't it take 5 users to close as a duplicate anymore? – CashCow Aug 07 '14 at 16:10
  • 1
    @CashCow I disagree with the duplicate, the use wants to loop *while* the `TAB` key is pressed, which can't be done in standard C. – Some programmer dude Aug 07 '14 at 16:10
  • @CashCow, That's for Linux, though. – chris Aug 07 '14 at 16:11
  • @JoachimPileborg Why? Wouldn't `getchar()` (or the equivalent in C++) and checking that against `'\t'` work? – Jashaszun Aug 07 '14 at 16:11
  • @CashCow, As of a month or two ago, gold tag badge users have veto dupe closing powers once per question. – chris Aug 07 '14 at 16:11
  • ok I will reopen as it is not an exact duplicate and I wasn't expecting my dupe to close it on my own.. – CashCow Aug 07 '14 at 16:13
  • 1
    @CashCow If you use e.g. `getchar` then the input have to be ended by a newline before the program can read the input. – Some programmer dude Aug 07 '14 at 16:13
  • To the OP, there are ways to read just a key, for example the [`_getch`](http://msdn.microsoft.com/en-us/library/078sfkak.aspx) function. – Some programmer dude Aug 07 '14 at 16:14
  • user has specified "winapi" so you can use a non-standard extension. – CashCow Aug 07 '14 at 16:15
  • 2
    Instead of `_getch`, I'd recommend `ReadConsoleInput`. – chris Aug 07 '14 at 16:15
  • Hello. Thanks for the quick comments. I'll see what I can come up with. The hotkey ([TAB] in this case) needs to be global, which is why I've used GetAsyncKeyState inside of the loop to only execute the code then that key is pressed. However, the infinite loop uselessly (is this a word?) drains cpu power so I figured I'd just pause the loop instead. – pnda Aug 07 '14 at 16:16
  • @JoachimPileborg - _loop while the TAB key is pressed, which can't be done in standard C_. Actually, it can. `GetAsyncKeyState()` is useful for stuff like that, and is usable in ANSI C. – ryyker Aug 07 '14 at 16:52
  • @ryyker No, the `GetAsyncKeyState` function is not *standard* C, it's a WIN32 function. – Some programmer dude Aug 07 '14 at 16:55
  • @JoachimPileborg - agreed. I should have modified that it can be done in C _using the winapi_. – ryyker Aug 07 '14 at 17:11

2 Answers2

1

You can use the function GetAsyncKeyState()

Here is an adaptation that does what you describe:
EDITED to allow exit of loop when SHIFT key is hit.

#include <stdio.h> //Use these includes: (may be different on your environment) 
#include <windows.h>

BOOL isKeyDown(int key)  ;
int main(void)
{
    int running = 1;
    while(running)
    {
        while(!isKeyDown(VK_TAB)); //VK_TAB & others defined in WinUser.h
        printf("Hello World");
        Delay(1.0);
        if(isKeyDown(VK_SHIFT)) running = 0;//<SHIFT> exits loop
    }

    return 0;   
}


BOOL isKeyDown(int key)
{
    int i;
    short res;

    res = GetAsyncKeyState(key);
    if((0x80000000 &res  != 0) || (0x00000001 & res != 0)) return TRUE; 

    return FALSE;   
}
ryyker
  • 22,849
  • 3
  • 43
  • 87
  • Hello. Thanks for trying to help out, although this doesn't really solve my problem. In this case, there's still an endless loop running, which is bad. But maybe you can't avoid this loop? – pnda Aug 07 '14 at 16:54
  • @user3052603 see my edit (in about two minutes). Will modify while(1) to while(running) – ryyker Aug 07 '14 at 16:57
0

I don't know if you are planning to use threads... But I came up with a solution that places the loop inside a thread and then, on the main thread, checks for the TAB key state. If the key is pressed the main thread awakes the loop thread, if it is not pressed, the main thread hangs the loop thread. Check it out:

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

using namespace std;

bool running = false;

DWORD WINAPI thread(LPVOID arg)
{
    while (1)
    {
        cout << "Hello world" << endl;
    }
}

void controlThread(void)
{
    short keystate = GetAsyncKeyState(VK_TAB);
    if(!running && keystate < 0)
    {
        ResumeThread(h_thread);
        running = true;
    }
    else if(running && keystate >= 0)
    {
        SuspendThread(h_thread);
        running = false;
    }
}
int main(void)
{
    HANDLE h_thread;

    h_thread = CreateThread(NULL,0,thread,NULL,0,NULL);
    SuspendThread(h_thread);

    while(1)
    {
        controlThread();    
        //To not consume too many processing resources.
        Sleep(200);
    }
}

My main uses a loop to keep checking for the keypress forever... But you can do that on specific points of your program, avoiding that infinite loop.

igor.araujo
  • 1,007
  • 1
  • 7
  • 15