如何在linux下,实现getch函数功能

时间:2021-06-28 16:15:29
getch();接受一个任意键的输入,不用按回车就返回。该函数的返回值是所输入字符的ASCII码,且该函数的输入不会自动显示在屏幕上,需要putchar();函数输出显示。getch();函数常用于中途暂停程序方便调试和查看。
有没有办法自己用c语言封装一个在linux下的getch函数?

9 个解决方案

#1


看看这个!

[code=c/****************************************
文件名: getkey.h
版本: 1.0
此头文件包含函数:
int getch()
char *getkey()
可用于获取按键信息,具体返回值请自行
测试,编译需加参数 -lpthread
此头文件适用平台:
诺亚舟同步搜学王NP1500/I新春版
             made by pengyao1207
注:C++不可用             2013年8月
****************************************/
#include <linux/unistd.h>
#include <termios.h>
#include <unistd.h>  
#include <stdio.h>
#include <pthread.h>
#ifndef _PY_GETKER_H
#define _PY_GETKEY_H
int input;
pthread_t thread[1];
pthread_mutex_t mut;
char c[193]="";
void *memset();
void *regetch()
{
        int n = 0;
        n = fgetc( stdin );
        input += n;
        pthread_exit(NULL);
}
int getch( void )

        struct termios tm, tm_old; 
        int fd = STDIN_FILENO,c;

        if(tcgetattr(fd, &tm) < 0) 
        return -1; 

        tm_old = tm; 

        cfmakeraw(&tm); 

        if(tcsetattr(fd, TCSANOW, &tm) < 0) 
        return -1; 

        unsigned int k;
        int temp;
        input = fgetc( stdin );
        k = input;
        if(tcsetattr(fd,TCSANOW,&tm_old)<0) return -1;
        if(k > 32){
                c = k;
        }
        else{
                while(1)
                {
                        memset(&thread,0,sizeof(thread));
                        if((temp = pthread_create(&thread[0],NULL,regetch,NULL))!=0)
                        printf("用于获取按键输入的线程创建失败!\n");
                        usleep(1000);
                        pthread_cancel(thread[0]);
                        pthread_join(thread[0],NULL);
                        if(k == input) {
                                c=input; 
                                break;
                        }
                        else{ 
                                k = input;
                                c=c+k;
                        }
                }
        }
        return c; 

char *getkey(void)
{
int n,i;
char a;
c[0]='"';
n=getch();
switch(n)
{
case 171:
   return "UP";
case 172:
   return "DOWN";
case 173:
   return "RIGHT";
case 174:
   return "LEFT";
case 27:
   return "ESC";
case 13:
   return "OK";
case 342:
   return "AA";
case 343:
   return "BB";
case 127:
   return "DEL";
case 32:
   return "SPACE";
case 39:
return c;
}
if(n>96)if(n<123)
{
a='a';
for(i=97;i<n;i++)a++;
c[0]=a;
return c;
}
if(n>64)if(n<91)
{
a='A';
for(i=65;i<n;i++)a++;
c[0]=a;
return c;
}
}
#endif][/code]

#2


好的,我试试,谢谢

#3


参考NUCRSES库?

#4


引用 1 楼 baidu_30174103 的回复:
看看这个!

[code=c/****************************************
文件名: getkey.h
版本: 1.0
此头文件包含函数:
int getch()
char *getkey()
可用于获取按键信息,具体返回值请自行
测试,编译需加参数 -lpthread
此头文件适用平台:
诺亚舟同步搜学王NP1500/I新春版
             made by pengyao1207
注:C++不可用             2013年8月
****************************************/
#include <linux/unistd.h>
#include <termios.h>
#include <unistd.h>  
#include <stdio.h>
#include <pthread.h>
#ifndef _PY_GETKER_H
#define _PY_GETKEY_H
int input;
pthread_t thread[1];
pthread_mutex_t mut;
char c[193]="";
void *memset();
void *regetch()
{
        int n = 0;
        n = fgetc( stdin );
        input += n;
        pthread_exit(NULL);
}
int getch( void )

        struct termios tm, tm_old; 
        int fd = STDIN_FILENO,c;

        if(tcgetattr(fd, &tm) < 0) 
        return -1; 

        tm_old = tm; 

        cfmakeraw(&tm); 

        if(tcsetattr(fd, TCSANOW, &tm) < 0) 
        return -1; 

        unsigned int k;
        int temp;
        input = fgetc( stdin );
        k = input;
        if(tcsetattr(fd,TCSANOW,&tm_old)<0) return -1;
        if(k > 32){
                c = k;
        }
        else{
                while(1)
                {
                        memset(&thread,0,sizeof(thread));
                        if((temp = pthread_create(&thread[0],NULL,regetch,NULL))!=0)
                        printf("用于获取按键输入的线程创建失败!\n");
                        usleep(1000);
                        pthread_cancel(thread[0]);
                        pthread_join(thread[0],NULL);
                        if(k == input) {
                                c=input; 
                                break;
                        }
                        else{ 
                                k = input;
                                c=c+k;
                        }
                }
        }
        return c; 

char *getkey(void)
{
int n,i;
char a;
c[0]='"';
n=getch();
switch(n)
{
case 171:
   return "UP";
case 172:
   return "DOWN";
case 173:
   return "RIGHT";
case 174:
   return "LEFT";
case 27:
   return "ESC";
case 13:
   return "OK";
case 342:
   return "AA";
case 343:
   return "BB";
case 127:
   return "DEL";
case 32:
   return "SPACE";
case 39:
return c;
}
if(n>96)if(n<123)
{
a='a';
for(i=97;i<n;i++)a++;
c[0]=a;
return c;
}
if(n>64)if(n<91)
{
a='A';
for(i=65;i<n;i++)a++;
c[0]=a;
return c;
}
}
#endif][/code]

不知道为什么只要运行getch,测试代码如下面
如何在linux下,实现getch函数功能
但是输入就是没有反应,而且CTRL+c或者ctrl + \,也无法退出运行,

#5


引用 3 楼 zhao4zhong1 的回复:
参考NUCRSES库?


怎么引用 如何在linux下,实现getch函数功能
我不会啊, 如何在linux下,实现getch函数功能

#6


#include "getkey.h"
main()
{
printf("%s",getkey());
/*printf("%d",getch());*/
}
试试,我当时测试用的。

#7


引用 4 楼 qq_35398857 的回复:
Quote: 引用 1 楼 baidu_30174103 的回复:

看看这个!

[code=c/****************************************
文件名: getkey.h
版本: 1.0
此头文件包含函数:
int getch()
char *getkey()
可用于获取按键信息,具体返回值请自行
测试,编译需加参数 -lpthread
此头文件适用平台:
诺亚舟同步搜学王NP1500/I新春版
             made by pengyao1207
注:C++不可用             2013年8月
****************************************/
#include <linux/unistd.h>
#include <termios.h>
#include <unistd.h>  
#include <stdio.h>
#include <pthread.h>
#ifndef _PY_GETKER_H
#define _PY_GETKEY_H
int input;
pthread_t thread[1];
pthread_mutex_t mut;
char c[193]="";
void *memset();
void *regetch()
{
        int n = 0;
        n = fgetc( stdin );
        input += n;
        pthread_exit(NULL);
}
int getch( void )

        struct termios tm, tm_old; 
        int fd = STDIN_FILENO,c;

        if(tcgetattr(fd, &tm) < 0) 
        return -1; 

        tm_old = tm; 

        cfmakeraw(&tm); 

        if(tcsetattr(fd, TCSANOW, &tm) < 0) 
        return -1; 

        unsigned int k;
        int temp;
        input = fgetc( stdin );
        k = input;
        if(tcsetattr(fd,TCSANOW,&tm_old)<0) return -1;
        if(k > 32){
                c = k;
        }
        else{
                while(1)
                {
                        memset(&thread,0,sizeof(thread));
                        if((temp = pthread_create(&thread[0],NULL,regetch,NULL))!=0)
                        printf("用于获取按键输入的线程创建失败!\n");
                        usleep(1000);
                        pthread_cancel(thread[0]);
                        pthread_join(thread[0],NULL);
                        if(k == input) {
                                c=input; 
                                break;
                        }
                        else{ 
                                k = input;
                                c=c+k;
                        }
                }
        }
        return c; 

char *getkey(void)
{
int n,i;
char a;
c[0]='"';
n=getch();
switch(n)
{
case 171:
   return "UP";
case 172:
   return "DOWN";
case 173:
   return "RIGHT";
case 174:
   return "LEFT";
case 27:
   return "ESC";
case 13:
   return "OK";
case 342:
   return "AA";
case 343:
   return "BB";
case 127:
   return "DEL";
case 32:
   return "SPACE";
case 39:
return c;
}
if(n>96)if(n<123)
{
a='a';
for(i=97;i<n;i++)a++;
c[0]=a;
return c;
}
if(n>64)if(n<91)
{
a='A';
for(i=65;i<n;i++)a++;
c[0]=a;
return c;
}
}
#endif][/code]

不知道为什么只要运行getch,测试代码如下面
如何在linux下,实现getch函数功能
但是输入就是没有反应,而且CTRL+c或者ctrl + \,也无法退出运行,



getch()返回int

#8


#include <termio.h>

int getch(void)
{
     struct termios tm, tm_old;
     int fd = 0, ch;
 
     if (tcgetattr(fd, &tm) < 0) {//保存现在的终端设置
          return -1;
     }
 
     tm_old = tm;
     cfmakeraw(&tm);//更改终端设置为原始模式,该模式下所有的输入数据以字节为单位被处理
     if (tcsetattr(fd, TCSANOW, &tm) < 0) {//设置上更改之后的设置
          return -1;
     }
 
     ch = getchar();
     if (tcsetattr(fd, TCSANOW, &tm_old) < 0) {//更改设置为最初的样子
          return -1;
     }
    
     return ch;
}


总体的思路就是设置终端的属性

设置为原始模式,这种模式下输入就是无缓冲的,

设置过去,输入完之后然后再更改回来

主要就是两个函数

tcgetattr()和tcsetattr()

这个可以百度获取详细信息

#1


看看这个!

[code=c/****************************************
文件名: getkey.h
版本: 1.0
此头文件包含函数:
int getch()
char *getkey()
可用于获取按键信息,具体返回值请自行
测试,编译需加参数 -lpthread
此头文件适用平台:
诺亚舟同步搜学王NP1500/I新春版
             made by pengyao1207
注:C++不可用             2013年8月
****************************************/
#include <linux/unistd.h>
#include <termios.h>
#include <unistd.h>  
#include <stdio.h>
#include <pthread.h>
#ifndef _PY_GETKER_H
#define _PY_GETKEY_H
int input;
pthread_t thread[1];
pthread_mutex_t mut;
char c[193]="";
void *memset();
void *regetch()
{
        int n = 0;
        n = fgetc( stdin );
        input += n;
        pthread_exit(NULL);
}
int getch( void )

        struct termios tm, tm_old; 
        int fd = STDIN_FILENO,c;

        if(tcgetattr(fd, &tm) < 0) 
        return -1; 

        tm_old = tm; 

        cfmakeraw(&tm); 

        if(tcsetattr(fd, TCSANOW, &tm) < 0) 
        return -1; 

        unsigned int k;
        int temp;
        input = fgetc( stdin );
        k = input;
        if(tcsetattr(fd,TCSANOW,&tm_old)<0) return -1;
        if(k > 32){
                c = k;
        }
        else{
                while(1)
                {
                        memset(&thread,0,sizeof(thread));
                        if((temp = pthread_create(&thread[0],NULL,regetch,NULL))!=0)
                        printf("用于获取按键输入的线程创建失败!\n");
                        usleep(1000);
                        pthread_cancel(thread[0]);
                        pthread_join(thread[0],NULL);
                        if(k == input) {
                                c=input; 
                                break;
                        }
                        else{ 
                                k = input;
                                c=c+k;
                        }
                }
        }
        return c; 

char *getkey(void)
{
int n,i;
char a;
c[0]='"';
n=getch();
switch(n)
{
case 171:
   return "UP";
case 172:
   return "DOWN";
case 173:
   return "RIGHT";
case 174:
   return "LEFT";
case 27:
   return "ESC";
case 13:
   return "OK";
case 342:
   return "AA";
case 343:
   return "BB";
case 127:
   return "DEL";
case 32:
   return "SPACE";
case 39:
return c;
}
if(n>96)if(n<123)
{
a='a';
for(i=97;i<n;i++)a++;
c[0]=a;
return c;
}
if(n>64)if(n<91)
{
a='A';
for(i=65;i<n;i++)a++;
c[0]=a;
return c;
}
}
#endif][/code]

#2


好的,我试试,谢谢

#3


参考NUCRSES库?

#4


引用 1 楼 baidu_30174103 的回复:
看看这个!

[code=c/****************************************
文件名: getkey.h
版本: 1.0
此头文件包含函数:
int getch()
char *getkey()
可用于获取按键信息,具体返回值请自行
测试,编译需加参数 -lpthread
此头文件适用平台:
诺亚舟同步搜学王NP1500/I新春版
             made by pengyao1207
注:C++不可用             2013年8月
****************************************/
#include <linux/unistd.h>
#include <termios.h>
#include <unistd.h>  
#include <stdio.h>
#include <pthread.h>
#ifndef _PY_GETKER_H
#define _PY_GETKEY_H
int input;
pthread_t thread[1];
pthread_mutex_t mut;
char c[193]="";
void *memset();
void *regetch()
{
        int n = 0;
        n = fgetc( stdin );
        input += n;
        pthread_exit(NULL);
}
int getch( void )

        struct termios tm, tm_old; 
        int fd = STDIN_FILENO,c;

        if(tcgetattr(fd, &tm) < 0) 
        return -1; 

        tm_old = tm; 

        cfmakeraw(&tm); 

        if(tcsetattr(fd, TCSANOW, &tm) < 0) 
        return -1; 

        unsigned int k;
        int temp;
        input = fgetc( stdin );
        k = input;
        if(tcsetattr(fd,TCSANOW,&tm_old)<0) return -1;
        if(k > 32){
                c = k;
        }
        else{
                while(1)
                {
                        memset(&thread,0,sizeof(thread));
                        if((temp = pthread_create(&thread[0],NULL,regetch,NULL))!=0)
                        printf("用于获取按键输入的线程创建失败!\n");
                        usleep(1000);
                        pthread_cancel(thread[0]);
                        pthread_join(thread[0],NULL);
                        if(k == input) {
                                c=input; 
                                break;
                        }
                        else{ 
                                k = input;
                                c=c+k;
                        }
                }
        }
        return c; 

char *getkey(void)
{
int n,i;
char a;
c[0]='"';
n=getch();
switch(n)
{
case 171:
   return "UP";
case 172:
   return "DOWN";
case 173:
   return "RIGHT";
case 174:
   return "LEFT";
case 27:
   return "ESC";
case 13:
   return "OK";
case 342:
   return "AA";
case 343:
   return "BB";
case 127:
   return "DEL";
case 32:
   return "SPACE";
case 39:
return c;
}
if(n>96)if(n<123)
{
a='a';
for(i=97;i<n;i++)a++;
c[0]=a;
return c;
}
if(n>64)if(n<91)
{
a='A';
for(i=65;i<n;i++)a++;
c[0]=a;
return c;
}
}
#endif][/code]

不知道为什么只要运行getch,测试代码如下面
如何在linux下,实现getch函数功能
但是输入就是没有反应,而且CTRL+c或者ctrl + \,也无法退出运行,

#5


引用 3 楼 zhao4zhong1 的回复:
参考NUCRSES库?


怎么引用 如何在linux下,实现getch函数功能
我不会啊, 如何在linux下,实现getch函数功能

#6


#include "getkey.h"
main()
{
printf("%s",getkey());
/*printf("%d",getch());*/
}
试试,我当时测试用的。

#7


引用 4 楼 qq_35398857 的回复:
Quote: 引用 1 楼 baidu_30174103 的回复:

看看这个!

[code=c/****************************************
文件名: getkey.h
版本: 1.0
此头文件包含函数:
int getch()
char *getkey()
可用于获取按键信息,具体返回值请自行
测试,编译需加参数 -lpthread
此头文件适用平台:
诺亚舟同步搜学王NP1500/I新春版
             made by pengyao1207
注:C++不可用             2013年8月
****************************************/
#include <linux/unistd.h>
#include <termios.h>
#include <unistd.h>  
#include <stdio.h>
#include <pthread.h>
#ifndef _PY_GETKER_H
#define _PY_GETKEY_H
int input;
pthread_t thread[1];
pthread_mutex_t mut;
char c[193]="";
void *memset();
void *regetch()
{
        int n = 0;
        n = fgetc( stdin );
        input += n;
        pthread_exit(NULL);
}
int getch( void )

        struct termios tm, tm_old; 
        int fd = STDIN_FILENO,c;

        if(tcgetattr(fd, &tm) < 0) 
        return -1; 

        tm_old = tm; 

        cfmakeraw(&tm); 

        if(tcsetattr(fd, TCSANOW, &tm) < 0) 
        return -1; 

        unsigned int k;
        int temp;
        input = fgetc( stdin );
        k = input;
        if(tcsetattr(fd,TCSANOW,&tm_old)<0) return -1;
        if(k > 32){
                c = k;
        }
        else{
                while(1)
                {
                        memset(&thread,0,sizeof(thread));
                        if((temp = pthread_create(&thread[0],NULL,regetch,NULL))!=0)
                        printf("用于获取按键输入的线程创建失败!\n");
                        usleep(1000);
                        pthread_cancel(thread[0]);
                        pthread_join(thread[0],NULL);
                        if(k == input) {
                                c=input; 
                                break;
                        }
                        else{ 
                                k = input;
                                c=c+k;
                        }
                }
        }
        return c; 

char *getkey(void)
{
int n,i;
char a;
c[0]='"';
n=getch();
switch(n)
{
case 171:
   return "UP";
case 172:
   return "DOWN";
case 173:
   return "RIGHT";
case 174:
   return "LEFT";
case 27:
   return "ESC";
case 13:
   return "OK";
case 342:
   return "AA";
case 343:
   return "BB";
case 127:
   return "DEL";
case 32:
   return "SPACE";
case 39:
return c;
}
if(n>96)if(n<123)
{
a='a';
for(i=97;i<n;i++)a++;
c[0]=a;
return c;
}
if(n>64)if(n<91)
{
a='A';
for(i=65;i<n;i++)a++;
c[0]=a;
return c;
}
}
#endif][/code]

不知道为什么只要运行getch,测试代码如下面
如何在linux下,实现getch函数功能
但是输入就是没有反应,而且CTRL+c或者ctrl + \,也无法退出运行,



getch()返回int

#8


#include <termio.h>

int getch(void)
{
     struct termios tm, tm_old;
     int fd = 0, ch;
 
     if (tcgetattr(fd, &tm) < 0) {//保存现在的终端设置
          return -1;
     }
 
     tm_old = tm;
     cfmakeraw(&tm);//更改终端设置为原始模式,该模式下所有的输入数据以字节为单位被处理
     if (tcsetattr(fd, TCSANOW, &tm) < 0) {//设置上更改之后的设置
          return -1;
     }
 
     ch = getchar();
     if (tcsetattr(fd, TCSANOW, &tm_old) < 0) {//更改设置为最初的样子
          return -1;
     }
    
     return ch;
}


总体的思路就是设置终端的属性

设置为原始模式,这种模式下输入就是无缓冲的,

设置过去,输入完之后然后再更改回来

主要就是两个函数

tcgetattr()和tcsetattr()

这个可以百度获取详细信息

#9