zoukankan      html  css  js  c++  java
  • 【C++】linux下监听键盘事件(按键后非阻塞读取,不用Enter)

    #include <termio.h>
    #include <stdio.h>
    
    int scanKeyboard()
    {
        int input;
        struct termios new_settings;
        struct termios stored_settings;
        tcgetattr(0,&stored_settings);
        new_settings = stored_settings;
        new_settings.c_lflag &= (~ICANON);
        new_settings.c_cc[VTIME] = 0;
        tcgetattr(0,&stored_settings);
        new_settings.c_cc[VMIN] = 1;
        tcsetattr(0,TCSANOW,&new_settings);
         
        in = getchar();
         
        tcsetattr(0,TCSANOW,&stored_settings);
        return input;
    }
    
    //返回该键的ASCII码值,不需回车
    

     

    解析:

    ICANON
    Enable canonical mode. This enables the special characters EOF, EOL, EOL2, ERASE, KILL, LNEXT, REPRINT, STATUS, and WERASE, and buffers by lines.

    可以看出 ICNAON 标志位启用了整行缓存。

    所以,new_settings.c_lflag &= (~ICANON);这句屏蔽整行缓存。那就只能单个了。

    通过tcsetattr函数设置terminal的属性来控制需不需要回车来结束输入。


    注:通过while循环读取键盘效率很低,参考使用异步事件或者多线程技术。单线程为阻塞式的

      

    【原文】https://blog.csdn.net/alangdangjia/article/details/27697721

    在windows下有个键盘测试函数,int kbhit(void)。使用该函数需要包含头文件conio.h。执行时,kbhit测试是否有键盘按键按下,若有则返回非零值,否则返回零。

    在Unix/Linux下,并没有提供这个函数。在linux下开发控制台程序时,有时会遇到检测键盘是否有被按下的情况,这时就需要自己编写 kbhit() 实现的程序了。

    #include <stdio.h>
    #include <termios.h>
     
    static struct termios initial_settings, new_settings;
    static int peek_character = -1;
    
    void init_keyboard(void);
    void close_keyboard(void);
    int kbhit(void);
    int readch(void); 
    
    void init_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);
    }
     
    void close_keyboard()
    {
    	tcsetattr(0, TCSANOW, &initial_settings);
    }
     
    int 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 readch()
    {
    	char ch;
     
    	if(peek_character != -1) 
    	{
    		ch = peek_character;
    		peek_character = -1;
    		return ch;
    	}
    	read(0,&ch,1);
    	return ch;
    }
     
    int main()
    {
    	init_keyboard();
    	while(1)
    	{
    		kbhit();
    		printf("
    %d
    ", readch());
    	}
    	close_keyboard();
    	return 0;
    }
    

     

    linux termios 结构:

    https://blog.csdn.net/querdaizhi/article/details/7436722

  • 相关阅读:
    关于排序算法的记录
    java获取src下文件
    学习HashMap的笔记
    红黑树删除
    学习红黑树过程中的个人总结
    关于二叉树的记录
    关于自动装箱和自动拆箱
    学习函数的时候问题
    Oracle 实现拆分列数据的split()方法
    福大软工 · 最终作业
  • 原文地址:https://www.cnblogs.com/SchrodingerDoggy/p/14072739.html
Copyright © 2011-2022 走看看