QQ登录

只需一步,快速开始

 找回密码
 注册

QQ登录

只需一步,快速开始

楼主: netdigger

怎么样才能在不中断程序运行的情况下取得键盘的输入?

[复制链接]
发表于 2002-11-29 11:44:59 | 显示全部楼层
http://my.nbip.net/homepage/unix/programs/a0139.html这里有点资料,但是是用于unix系统的,看看他的mygetch():
int mygetch()
{
int i;
char c;
struct termio *old_tbuf,tbuf;
ioctl(0,TCGETA,&old_tbuf);/* 取当前终端信息 */
tbuf=old_tbuf;
tbuf.c_lflag&=~ICANON;        /* 设为原始模式 */
tbuf.c_cc[VNUM]=1;/* 设最少输入一个字符 */
tbuf.c_cc[VTIME]=0;/* 等待时间为0 */
ioctl(0,TCSETA,&tbuf);
i=read(0,&c,1);
if(c==27){/* 如为27则为光标键前导码 */
read(0,&c,1);read(0,&c,1);
switch(c){
  case ‘A':return(56);break;/* UP */
  case ‘B':return(50);break;/* DOWN */
  case ‘C':return(54);break;/* RIGHT */
  case ‘D':return(52);break;/* LEFT */
  case 27:return(27);break;/* ESC */
}
ioctl(0,TCSETA,&old_tbuf);
return(c);
}
这个mygetch里面用到的大部分东西linux都有,只是termio结构有点不同,我还没移植成功,你看看该怎么弄?
回复

使用道具 举报

发表于 2002-11-29 13:19:13 | 显示全部楼层
找到了,好东西,赶紧看
http://www.linuxforum.net/forum/showflat.php?Cat=&Board=program&Number=339585&page=0&view=collapsed&sb=5&o=7&fpart=
回复

使用道具 举报

发表于 2002-11-29 15:08:34 | 显示全部楼层
我写了一个即时获得键盘输入的程序:
编译方法:gcc -o program_name xxx.c -lpthread
[code:1]
#include <stdlib.h>
#include <stdio.h>
#include <termios.h>
#include <string.h>
#include <pthread.h>

static struct termios stored_settings;

void set_keypress(void)
{
  struct termios new_settings;
  
  tcgetattr(0,&stored_settings);
  
  new_settings = stored_settings;
  
  /* Disable canonical mode, and set buffer size to 1 byte */
  new_settings.c_lflag &= (~ICANON);
  new_settings.c_cc[VTIME] = 0;
  new_settings.c_cc[VMIN] = 1;
  
  tcsetattr(0,TCSANOW,&new_settings);
  return;
     }

void reset_keypress(void)
{
  tcsetattr(0,TCSANOW,&stored_settings);
  return;
     }

void *
get_input(void *data)
{
  while(1)
    {
      *((int *)data)=getc(_IO_stdin);
      if(*((int *)data)=='q')
        break;
        }
  printf("I have exited!\n");
  pthread_exit(NULL);
}
main()
{
  int new_char=0;
  pthread_t new_thread;
  set_keypress();
  pthread_create(&new_thread,NULL,get_input,(void *)&new_char);/*创建一个线程,用来接收键盘输入,这样主线程就不会被阻塞了,线程函数是get_input。*/
  while(1)
    {
      if(new_char=='q')
        break;
      if(new_char)
        {
          printf("you press key:'%c'\n",new_char);
          new_char=0;
        }
      usleep(10000);//不加这句,该程序会把绝大部分CPU资源都占用了。
    }
  reset_keypress();
}
[/code:1]
回复

使用道具 举报

 楼主| 发表于 2002-11-29 15:38:46 | 显示全部楼层
谢谢mozilla。
有按键丢失现象以下是运行的部分内容:
yyou press key:'y'
ruhyou press key:'h'//这行ru丢失
guyou press key:'u'//g丢失
syou press key:'s'
bhuyou press key:'u'
fdnyou press key:'n'
vyou press key:'v'
nhyou press key:'h'
usiyou press key:'i'
hyou press key:'h'
guyou press key:'u'
sryou press key:'r'
qI have exited!
可能和usleep()有关。
回复

使用道具 举报

发表于 2002-11-29 16:20:39 | 显示全部楼层
对,把usleep(10000)改小点usleep(1000)试试。
回复

使用道具 举报

发表于 2002-11-30 04:12:49 | 显示全部楼层
带有 /*************/ 表示更改过的


[code:1]
#include <stdlib.h>
#include <stdio.h>
#include <termios.h>
#include <string.h>
#include <pthread.h>

static struct termios stored_settings;

void set_keypress(void)
{
  struct termios new_settings;

  tcgetattr(0,&stored_settings);

  new_settings = stored_settings;

  /* Disable canonical mode, and set buffer size to 1 byte */
  new_settings.c_lflag &= (~ICANON);
  new_settings.c_cc[VTIME] = 0;
  new_settings.c_cc[VMIN] = 1;

  tcsetattr(0,TCSANOW,&new_settings);
  return;
     }

void reset_keypress(void)
{
  tcsetattr(0,TCSANOW,&stored_settings);
  return;
     }

pthread_mutex_t mptr_key = PTHREAD_MUTEX_INITIALIZER; /*************/
pthread_cond_t cptr_key = PTHREAD_COND_INITIALIZER; /*************/

void *
get_input(void *data)
{
  while(1)
    {
      int key = getc(_IO_stdin);/*************/

      pthread_mutex_lock(&mptr_key);/*************/
      *((int *)data) = key;/*************/
      pthread_cond_signal(&cptr_key);/*************/
      if(*((int *)data)=='q')
      {/*************/
              pthread_mutex_unlock(&mptr_key);/*************/
              break;
      }/*************/
      pthread_mutex_unlock(&mptr_key);/*************/
   }
  printf("I have exited!\n");
  pthread_exit(NULL);
}
main()
{
  int new_char=0;
  pthread_t new_thread;
  set_keypress();
  pthread_create(&new_thread,NULL,get_input,(void *)&new_char);/*创建一个线程,用来接收键盘输入,这样主线程就不会被阻塞了,线程函数是get_input。*/
  while(1)
    {
     pthread_mutex_lock(&mptr_key);/*************/
      if(new_char == 0) if(pthread_cond_wait(&cptr_key, &mptr_key) != 0) continue;/*************/

      if(new_char=='q')
      {/*************/
        pthread_mutex_unlock(&mptr_key);/*************/
   break;
      }/*************/
      if(new_char)
   {
     printf("you press key:'%c'\n",new_char);
     new_char=0;
   }
//    usleep(10000);//不加这句,该程序会把绝大部分CPU资源都占用了。/**************/
      pthread_mutex_unlock(&mptr_key);/*************/
    }
  reset_keypress();
}
[/code:1]
回复

使用道具 举报

发表于 2002-12-2 16:49:35 | 显示全部楼层
我编译了你这个程序,可是我按一个健后必需回车才打印read n from keyboardxx
如果不按回车就一直打印timeout,这似乎没达到要求。


程序设计的目的本来就是定时检测键盘输入(每隔2.5秒),如果没有键盘输入,就会输出一个“timeout",如果有键盘输入,就转去读键盘并报告敲入的内容。这个程序是一个简单的示例程序,完全可以根据你自己的需要改写。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

GMT+8, 2024-11-16 17:49 , Processed in 0.039970 second(s), 12 queries .

© 2021 Powered by Discuz! X3.5.

快速回复 返回顶部 返回列表