C++: execute a while loop until a key is pressed e.g. Esc?
Asked Answered
O

5

12

Does anyone have a snippet of code that doesn't use windows.h to check for a key press within a while loop. Basically this code but without having to use windows.h to do it. I want to use it on Linux and Windows.

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

int main()
{
    bool exit = false;

    while(exit == false)
    {
        if (GetAsyncKeyState(VK_ESCAPE))
        {
            exit = true;
        }
        std::cout<<"press esc to exit! "<<std::endl;
    }

    std::cout<<"exited: "<<std::endl;

    return 0;
}
Owlet answered 1/4, 2013 at 4:8 Comment(7)
s/GetAsyncKeyState(VK_ESCAPE)/GetAsyncKeyState(VK_ESCAPE) & 0x8000.Romanticism
@Romanticism I'm sorry I don't understand what you mean.Owlet
Do you want a specific key to be pressed or any key?Derron
@Aswin Any key is fine.Owlet
It means you should replace the first with the second. It's specified that if the key is down, the MSB is on. Standard C++ doesn't have a portable solution for this that I know of. I suppose a multithreaded cin.get() kind of works, but I'm very iffy with doing that.Romanticism
I believe that this post might be duplicate of [this one][1]. [1]: #422360Irreversible
@Irreversible No because they didn't ask for this to be multi-platform. Check out the answer. Its similar but I wanted this to work on windows and linux. Believe me I searched all over google before asking this.Owlet
H
2

Your best bet is to create a custom "GetAsyncKeyState" function that will use #IFDEF for windows and linux to choose the appropriate GetAsyncKeyState() or equivalent.

No other way exists to achieve the desired result, the cin approach has its problems - such as the application must be in focus.

Highstepper answered 1/4, 2013 at 4:23 Comment(2)
Thats what I thought too. I don't like using #ifdef _WIN32 #endif #ifdef linux #endif but theres no other way I guess.Owlet
Another solution would be to have the implementation of such a function in two files, implement_linux.cpp and implement_windows.cpp for example, and simply compile and link with one of them depending on the system you're using. No #ifdef needed !Vandiver
I
8
#include <conio.h>
#include <iostream>

int main()
{
    char c;
    std::cout<<"press esc to exit! "<<std::endl;
    while(true)
    {
        c=getch();
        if (c==27)
          break;
    }

    std::cout<<"exited: "<<std::endl;

    return 0;
}
Illgotten answered 1/4, 2013 at 4:26 Comment(1)
So getch() just returns EOF with no input? Isn't getchar() more portable?Stranger
H
2

Your best bet is to create a custom "GetAsyncKeyState" function that will use #IFDEF for windows and linux to choose the appropriate GetAsyncKeyState() or equivalent.

No other way exists to achieve the desired result, the cin approach has its problems - such as the application must be in focus.

Highstepper answered 1/4, 2013 at 4:23 Comment(2)
Thats what I thought too. I don't like using #ifdef _WIN32 #endif #ifdef linux #endif but theres no other way I guess.Owlet
Another solution would be to have the implementation of such a function in two files, implement_linux.cpp and implement_windows.cpp for example, and simply compile and link with one of them depending on the system you're using. No #ifdef needed !Vandiver
B
1
char c;
while (cin >> c) {
...
}

ctrl-D terminates the above loop. It will continue so long as a char is entered.

Bloodandthunder answered 1/4, 2013 at 4:14 Comment(6)
I'm on windows XP right now. Tried it and it just hangs. I guess its normal.Owlet
@lost_with_coding, Yes, all input in standard C++ is blocking. I'm not particularly confident in hacks to change that behaviour.Romanticism
@Romanticism So there is no way to do this on windows without windows.h?Owlet
@lost_with_coding sorry for the misleading, windows does not have an equivalent key to ctrl-d.Bloodandthunder
I guess I could do #ifdef _WIN32 #endif #ifdef linux #endifOwlet
@lost_with_coding The function kbhit() in this post might be of some help: #1449824Bloodandthunder
M
-1

//simplest.

    #include <iostream>
    #include <conio.h>

using namespace std;
    int main()
    {

        char ch;
        bool loop=false;

      while(loop==false)
       {
        cout<<"press escape to end loop"<<endl;
        ch=getch();
        if(ch==27)
        loop=true;
       }
        cout<<"loop terminated"<<endl;
        return 0;
    }
Moseley answered 11/10, 2015 at 17:11 Comment(0)
A
-2
//its not the best but it works


#include <vector>
#define WINVER 0x0500
#include <windows.h>
#include <conio.h>
#include <iostream>

int main()
{
char c;
std::cout<<"press esc to exit! "<<std::endl;
while(true)
{

std::cout<<"executing code! , if code stops press any key to     continue or esc to stop"<<std::endl;


 INPUT ip;

// Set up a generic keyboard event.aa
ip.type = INPUT_KEYBOARD;
ip.ki.wScan = 0; // hardware scan code for key
ip.ki.time = 0;
ip.ki.dwExtraInfo = 0;

int lol =   65; //a key
    // Press the "A" key
ip.ki.wVk = lol; // virtual-key code for the "a" key
ip.ki.dwFlags = 0; // 0 for key press
SendInput(1, &ip, sizeof(INPUT));

// Release the "A" key
ip.ki.dwFlags = KEYEVENTF_KEYUP; // KEYEVENTF_KEYUP for key release
SendInput(1, &ip, sizeof(INPUT));

    c=getch();
    if (c==27)
      break;
  }

std::cout<<"exited: "<<std::endl;
return 0;
}
Anaplasty answered 17/6, 2016 at 18:45 Comment(1)
Please do not post the same answer to multiple questions. If the same information really answers both questions, then one question (usually the newer one) should be closed as a duplicate of the other. You can indicate this by voting to close it as a duplicate or, if you don't have enough reputation for that, raise a flag to indicate that it's a duplicate. Otherwise, be sure you tailor your answer to this question and don't just paste the same answer in multiple places.Manlove

© 2022 - 2024 — McMap. All rights reserved.