Stopping an infinite loop in C++ when key is press

2019-04-15 10:46发布

问题:

This question already has an answer here:

  • How to detect key presses in a Linux C GUI program without prompting the user? 4 answers

I have a program as given below:

#include<iostream>
using namespace std;
int main()
{
    while(true)
    {
        //do some task
        if(Any_key_pressed)
            break;
    }
return 0;
}

how can exit from the loop if any key is pressed.

C++ Compiler: GCC 4.2 and higher
OS: Linux-Mint

Thanks

回答1:

Standard C++ doesn't offer a way to do this. You will need a platform-specific API that tells you whether a key was pressed (or input is available on stdin, possibly) without blocking. Which means you need to tell us which platform you're using.



回答2:

Try this:

#include <iostream>
#include <stdio.h>
#include <termios.h>
#include <unistd.h>
#include <fcntl.h>

using namespace std;

int kbhit(void)
{
  struct termios oldt, newt;
  int ch;
  int oldf;

  tcgetattr(STDIN_FILENO, &oldt);
  newt = oldt;
  newt.c_lflag &= ~(ICANON | ECHO);
  tcsetattr(STDIN_FILENO, TCSANOW, &newt);
  oldf = fcntl(STDIN_FILENO, F_GETFL, 0);
  fcntl(STDIN_FILENO, F_SETFL, oldf | O_NONBLOCK);

  ch = getchar();

  tcsetattr(STDIN_FILENO, TCSANOW, &oldt);
  fcntl(STDIN_FILENO, F_SETFL, oldf);

  if(ch != EOF)
  {
    ungetc(ch, stdin);
    return 1;
  }

  return 0;
}

int main(void)
{

  while(!kbhit());

  cout<<"You pressed "<<(char)getchar();

  return 0;
}


回答3:

You could use SDL, which is (mostly) platform independent.

#include<SDL/SDL.h>
...
#include<iostream>
using namespace std;
int main()
{
    while(true)
    {
        //do some task
        SDL_Event event
        while(SDL_PollEvent(&event))
        {
            if(event.type==SDL_KEYDOWN)
            {
                break;
            }
        }
    }
return 0;
}

The above code works for Windows, Linux, MacOS as well as a nnumber of other OSes. As for how to set up SDL, there's a tutorial.



回答4:

You can use ncurses:

#include <iostream>
#include <ncurses.h>

int main ()
{
    initscr();              // initialize ncurses
    noecho();               // don't print character pressed to end the loop
    curs_set(0);            // don't display cursor
    cbreak();               // don't wait for user to press ENTER after pressing a key
    nodelay(stdscr, TRUE);  // The nodelay option causes getch to be a non-blocking call. If no input is ready, getch returns ERR. If disabled (bf is FALSE), getch waits until a key is pressed.

    int ch;

    printw("Let's play a game! Press any key to quit.\n\n");

    while (1) {                       // infinite loop
        if ((ch = getch()) == ERR) {  // check to see if no key has been pressed
            printw(".");              // if no key has been pressed do this stuff
            usleep(1000);
            refresh();
        } else {                      // if a key is pressed... 
            nodelay(stdscr, false);   // reset nodelay()
            clear();                  // clear the screen
            break;                    // exit loop
        }
    }

    mvprintw(LINES/2, COLS/2-9, "Game Over");
    refresh();
    getch();  // wait for character, just so the program doesn't finish and exit before we read "Game Over" 
    endwin(); // terminate ncurses
    return 0;
}