UNIX_C 环境下实现输入一个字符,不用回车直接输入功能(类型windows下_getch(void)函数)

在UNIX C环境中,可以使用`<termios.h>`和`<unistd.h>`库来实现类似Windows下的`_getch()`功能,即输入一个字符而无需回车。通过`tcgetattr()`和`tcsetattr()`函数获取并修改终端属性,去除ICANON和ECHO标志以关闭标准输入模式和回显功能。同时设置`c_cc[VMIN]`为1,确保读取一个字符即可。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


UNIX_C 环境下实现输入一个字符,不用回车直接输入功能(类型windows下_getch(void)函数)


/*
	int getch ( void );		
	输入流获取一个信号当键盘输入一个字符时,
	不用回车不会会写,直接读取输入的字符并继续运行

	//linux 标准头文件库
	
	#include <unistd.h>
	#include <sys/ioctl.h>
	#include <termios.h>
	
	//windows 标准头文件库
	#include <conio.h>

	//调用函数
	int ch = getch();
*/

#ifdef WIN32
//windows 默认函数
//int __cdecl _getch(void);

#else
	
//linux 环境下代码	
int getch(void)
{
	struct termios term_old;
	ioctl( STDIN_FILENO, TCGETS, &term_old );
	struct termios term_new = term_old;
	term_new.c_lflag &= ~( ECHO | ICANON ); //取消会写与回车
	ioctl( STDIN_FILENO, TCSETS, &term_new );
	int ch = getchar();
	ioctl(STDIN_FILENO, TCSETS, &term_old);
	return ch;
}

</pre><pre code_snippet_id="1748202" snippet_file_name="blog_20160706_1_4593356" name="code" class="html">
<span style="font-size:18px;color:#ff0000;"><strong>编程实践教程》一书,里面有较详细的讲解,现将以上技巧如果实现及代码优化如下,还会不断改进</strong></span>

终端规范模式开启于关闭,使得缓冲和编辑失效

     #include <termios.h>

     #include<unistd.h>

    int tcgetattr(int fd, structtermios *termios_p);

         参 1:设备终端的文件描述符:0——标准输入,1——标准输出,2——标准错误

         参 2:struct termios original_mode{

                 ……

                   tcflag_t c_lflag;    //本地模式标志,控制终端编辑功能

                 cc_t     c_cc[NCCS]; 

              };

                   c_lflag:ICANON —— 使用标准输入模式

                        eg:original_mode.c_lflag&= ~ICANON ——  去除标准输入模式

                            ECHO   —— 回显功能

                        eg:original_mode.c_lflag&= ~ECHO   —— 关闭回显功能

                   c_cc[NCCS]:控制字符,用于保存终端驱动程序中的特殊字符,如输入结束符等

                         NCCS: VMIN —— 非规范模式读取时的最小字符数

                            eg:original_mode.c_c[VMIN] =1

         功能:用于获取与终端相关的参数,返回的结果保存在termios结构体中

    int tcsetattr(int fd, int optional_actions, const struct termios*termios_p);

         参 1:fd为打开的终端文件描述符,一般给 0;

         参 2:optional_actions用于控制修改起作用的时间

                * TCSANOW:     不等数据传输完毕就立即改变属性

         参 3:而结构体termios_p中保存了要修改的参数

         返回:函数在成功的时候返回0,失败的时候返回-1

         功能:用于设置终端参数参数参数



//终端规范模式的关闭与开启
//实现缓冲和编辑失效

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <termios.h>
#include <unistd.h>
#include <fcntl.h>
#include <signal.h>
int tty_mode( int flg )
{
	static struct termios mode;
	
	if( 0 ==  flg )
	{
		//获取
		if( !0 == tcgetattr(0, &mode) )
		{
			perror("tcgetattr error");
			return -1;
		}
		
	}
	else if( 1 == flg )
	{
		//设置
		if( -1 == tcsetattr(0, TCSANOW, &mode) )
		{
			perror("tcgetattr error");
			return -1;
		}
	}
	else
	{
		return -1;
	}

	return 0;
}

int set_tty_mode(void)
{
	struct termios new_mode;
	//获取当前终端参数信息
	if( !0 == tcgetattr(0, &new_mode))
	{
		perror("tcgetattr error");
		return -1;
	}
	
	//去除标准输入模式
	new_mode.c_lflag &= ~ICANON;

	//关闭回显功能
	new_mode.c_lflag &= ~ECHO; 
	
	//非规范模式下读取一个字符
	new_mode.c_cc[VMIN] = 1;

	if(-1 == tcsetattr(0, TCSANOW, &new_mode) )
	{
		perror("tcstattr error");
		return -1;
	}

	return 0;
}

int choose( void )
{
	printf("是否继续输入<Y/N>:");
	
	char c = getchar();

	switch(c)
	{
		case 'Y':
		case 'y':
			printf("\n");
			printf("将继续输入!\n");
			return 0;
		case 'N':
		case 'n':
			printf("\n");
			printf("将退出程序!\n");
			return 0;
		default:
			return -1;
	}
	
}

//当exit退出时将调用次函数恢复当前值
void atexit_function( void )
{
	int res = tty_mode(1);	//还原终端相关参数信息
	if( -1 == res )
	{
		printf("终端设置失败!\n");
		exit(1);
	}

	exit(1);
}

//或signal SIGINT信号将激活此函数
void signal_function( int  signum )
{
	int res = tty_mode(1);	//还原终端相关参数信息
	if( -1 == res )
	{
		printf("终端设置失败!\n");
		exit(1);
	}

	exit(1);
}

int main( void )
{
	atexit( atexit_function );

	if( SIG_ERR  == signal(SIGINT, signal_function) )
	{
		perror("signale error");
		_Exit(1);
	}
	int res = tty_mode(0);	//获取终端相关参数信息
	if( -1 == res )
	{
		printf("终端获取失败!\n");
		_Exit(1);
	}

	//设置终端非规范模式
	res = set_tty_mode();

	res = choose();	
	if(-1 == res )
	{
		printf("选择失败!\n");
		exit(1);
	}

}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值