17

Windows では、ループを中断せずに入力を探す次のコードがあります。

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

int main()
{
    while (true)
    {
        if (_kbhit())
        {
            if (_getch() == 'g')
            {
                std::cout << "You pressed G" << std::endl;
            }
        }
        Sleep(500);
        std::cout << "Running" << std::endl;
    }
}

ただし、conio.hLinux でこれとまったく同じことを実現する最も簡単な方法は何ですか?

4

5 に答える 5

16

お使いの Linux にconio.hサポートされていないkbhit()場合は、Morgan Mattews のコードkbhit()を参照 して、POSIX 準拠のシステムと互換性のある方法で機能を提供してください。

トリックは termios レベルでバッファリングを非アクティブ化するため、ここでgetchar()示されているように問題も解決するはずです。

于 2015-03-29T22:40:13.270 に答える
13

上で引用した ncurses のハウツーが役に立ちます。以下は、conio の例のように ncurses を使用する方法を示す例です。

#include <ncurses.h>

int
main()
{
    initscr();
    cbreak();
    noecho();
    scrollok(stdscr, TRUE);
    nodelay(stdscr, TRUE);
    while (true) {
        if (getch() == 'g') {
            printw("You pressed G\n");
        }
        napms(500);
        printw("Running\n");
    }
}

iostreamncurses では、ヘッダーは使用されないことに注意してください。これは、stdio と ncurses を混在させると、予期しない結果が生じる可能性があるためです。

ちなみに、ncurses は と を定義TRUEしてFALSEいます。bool正しく構成された ncurses は、ncurses の構成に使用される C++ コンパイラと同じデータ型を ncurses に使用します。

于 2015-03-29T23:07:58.283 に答える
3

ncurses を使用することは、Turbo C の「conio.h」API と機能的に同等ですが、より完全な解決策は、ここにあるように、conio 実装を使用することです

これをダウンロードしてプログラムで使用すると、Linux で conio インターフェースを完全に実装できます。(または OSX。) Ron Burkey によって書かれました。

于 2015-03-29T23:13:31.367 に答える
0

Linux を使用している場合は、独自のローカル ライブラリを作成できる次のソリューションを見つけました。

http://linux-sxs.org/programming/kbhit.html

kbhit.cpp


#include "kbhit.h"
#include <unistd.h> // read()
    
keyboard::keyboard(){
    tcgetattr(0,&initial_settings);
    new_settings = initial_settings;
    new_settings.c_lflag &= ~ICANON;
    new_settings.c_lflag &= ~ECHO;
    new_settings.c_lflag &= ~ISIG;
    new_settings.c_cc[VMIN] = 1;
    new_settings.c_cc[VTIME] = 0;
    tcsetattr(0, TCSANOW, &new_settings);
    peek_character=-1;
}
    
keyboard::~keyboard(){
    tcsetattr(0, TCSANOW, &initial_settings);
}
    
int keyboard::kbhit(){
    unsigned char ch;
    int nread;
    if (peek_character != -1) return 1;
    new_settings.c_cc[VMIN]=0;
    tcsetattr(0, TCSANOW, &new_settings);
    nread = read(0,&ch,1);
    new_settings.c_cc[VMIN]=1;
    tcsetattr(0, TCSANOW, &new_settings);

    if (nread == 1){
        peek_character = ch;
        return 1;
    }
    return 0;
}
    
int keyboard::getch(){
    char ch;

    if (peek_character != -1){
        ch = peek_character;
        peek_character = -1;
    }
    else read(0,&ch,1);
    return ch;
}

kbhit.h

#ifndef KBHIT_H
#define KBHIT_H
    
#include <termios.h>
    
class keyboard{
    public:
        keyboard();
        ~keyboard();
        int kbhit();
        int getch();

    private:
        struct termios initial_settings, new_settings;
        int peek_character;
};
    
#endif

main.cpp 内にインスタンスを作成しました。

#include "kbhit.h"

int main(){
    int key_nr;
    char key;
    keyboard keyb;
    while(true){
        if( keyb.kbhit() ){
            key_nr = keyb.getch(); //return int
            key = key_nr; // get ascii char
            // do some stuff
        }
    }
    return 0;
}
于 2020-09-02T15:30:05.020 に答える