一、kbhit() 和 getch()

C语言中kbhit()函数(conio.h):检查当前是否有键盘输入,若有则返回一个非0值,否则返回0。

getch()函数,不需要回车就可以得到输入的控制字符;

一般kbhit()和getch() 搭配使用!

1、应用举例:

#include<stdio.h>
#include<conio.h>
int main()
{
	int a;
	a = _kbhit();
	printf("%d\n",a);
	return 0;
}

运行结果:

 2、下面是一个实例,用户每按一次任意按键,屏幕都会打印一句:"The user presses a key.",下面是程序源代码:

#include<stdio.h>
#include<conio.h>
int main()
{
	while (1) {
		if (_kbhit()) {
			printf("The user presses a key.\n");
			_getch();
		}
	}
	return 0;
}
 

运行结果:

3、用户按任意键,退出程序:

#include <graphics.h>
#include <stdlib.h>
#include <conio.h>
#include <time.h>

void main()
{
	srand((unsigned)time(NULL));
	initgraph(640, 480);
	int x, y, c;
	while (!kbhit())
	{
		x = rand() % 640;
		y = rand() % 480;
		c = RGB(rand() % 256, rand() % 256, rand() % 256);
		putpixel(x, y, c);
		//Sleep(10);
	}
	closegraph();
}

 

 C_kbhit()和getch()函数的使用

结合一起使用:

char input;
if (kbhit())
{
    input = getch();
    if (input == '1')
            …………

搭配使用代码:

#include <graphics.h>
#include <stdio.h>
#include <conio.h>

void main()
{
	char c = 0;
	while (c != 27)
	{
		if (kbhit())
			c = getch();
		else
			c = '.';
		printf("%c", c);
		Sleep(100);
	}
}

运行结果:

 

3、getch()和getche()区别:

相同点:两个函数都不需要回车就可以得到输入的控制字符;

不同点:getch()函数,输入字符后,在屏幕上不显示(不回显);而getche()函数,输入字符后,在屏幕上显示(回显)

运行代码:

(1)、getch()

(2)、getche():

参考链接:getch(),getche(),getchar()的区别 (综合转)

二、gets()和getchar()

问题1:分析scanf()和getchar()读取字符

1、scanf输入:

输入字符:q,然后回车

#include <stdio.h>
int main() {

	char c1, c2;
	scanf("%c",&c1);
	scanf("%c",&c2);
	if (c2 == '\n')
	{
		c2 = 'a';
	}
	printf("c1=%c,c2=%c", c1, c2);
	return 0;
}

运行结果:

输入字符:qw,然后回车 

2、getchar()输入:

#include <stdio.h>
int main() {

	char c1, c2;
	c1=getchar(); //输入qw
	c2=getchar();
	if (c2 == '\n')
	{
		c2 = 'a';
	}
	printf("c1=%c,c2=%c", c1, c2);
	return 0;
}

运行结果:

运行结果:

【分析】:
    首先我们呢看一下输入操作的原理, 程序的输入都建有一个缓冲区,即输入缓冲区。一次输入过程是这样的,当一次键盘输入结束时会将输入的数据存入输入缓冲区,而cin函数直接从输入缓冲区中 取数据。正因为cin函数是直接从缓冲区取数据的,所以有时候当缓冲区中有残留数据时,cin函数会直接取得这些残留数据而不会请求键盘输入,这就是例子 中为什么会出现输入语句失效的原因!
    因为scanf()和getchar()函数是从输入流缓冲区中读取值的,而并非从键盘(也就是终端)缓冲区读取,而是读取时遇到回车(\n)而结束的,这个\n会一起读入输入流缓冲区的,所以第一次接受输入时取走字符后会留下字符\n,这样第二次的读入函数直接从缓冲区中 把\n取走了,显然读取成功了,所以不会再从终端读取!这就是为什么这个程序只执行了一次输入操作就结束的原因!

问题2:分析scanf()和gets()读取字符串

 1、scanf()输入:

#include <stdio.h>
int main() {

	char c1[100], c2[100];
	scanf("%s",c1);
	scanf("%s",c2);
	printf("c1[]=%s\n",c1);
	printf("c2[]=%s\n",c2);
	return 0;
}

 运行结果:

 【分 析】到此程序执行完毕,不会执行第二次的读取操作!这个问题的原因跟问题一类似,第一次输入Hello world!后,字符串Hello world!都会被读到输入缓冲区中,而scanf()函数取数据是遇到回车、空格、TAB就会停止,也就是第一个scanf()会取出"Hello", 而"world!"还在缓冲区中,这样第二个scanf会直接取出这些数据,而不会等待从终端输入。

 

 【分析】程序执行了两次从键盘读入字符串,说明第一次输入结束时的回车符被丢弃!即:scanf()读取字符串会舍弃最后的回车符!

既:遇见空格 回车 TAB键,读取停止,如果还有读取控制,则对缓冲区剩余字符读取!

2、gets()输入:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main() {

	char c1[100], c2[100];
	gets_s(c1);
	gets_s(c2);
	printf("c1=%s\n",c1);
	printf("c2=%s\n",c2);
	return 0;
}

运行结果

 【分析】显然与上一个程序的执行情况不同,这次程序执行了两次从键盘的读入,而且第一个字符串取了Hello world! 接受了空格符,而没有像上一个程序那样分成了两个字符串!所以如果要读入一个带空格符、Tab键的字符串时因该用gets(), 而不宜用scanf() !

问题3:getchar()暂停程序,查看程序执行结果:

不知道大家有没有遇到过这样的问题,有的编译器程序执行完后的结果界面不会停下而是一闪就没了,以至于看不到执行结果。所以很多人在程序最后加上 getchar()语句,目的是想让程序执行完后停下来,等待从终端接收一个字符再结束程序。可是发现有时候这样根本没用,程序照样跳出去了。这是为什么 呢?
【分析】原因跟上面例子讲的一样,是因为输入缓冲区中还有数据,所以getchar()会读到数据,所以就跳出了!

总结:

第一:要注意不同的函数是否接受空格符、是否舍弃最后的回车符的问题!
读取字符时:
scanf()以Space、Enter、Tab结束一次输入,不会舍弃最后的回车符(即回车符会残留在缓冲区中);
getchar()以Enter结束输入,也不会舍弃最后的回车符;
读取字符串时:
scanf()以Space、Enter、Tab结束一次输入
gets()以Enter结束输入(空格不结束),接受空格,会舍弃最后的回车符!

第二:为了避免出现上述问题,必须要清空缓冲区的残留数据,可以用以下的方法解决:
方法1:C语言里提供了函数清空缓冲区,只要在读数据之前先清空缓冲区就没问题了!
       这个函数是fflush(stdin)。
方法2:自己取出缓冲区里的残留数据。
(说实话这个语句我也没看懂,呵呵!为什么格式控制是这样的!希望高手指点一下!)
       scanf("%[^\n]",string);

gets()和getchar()的用法

Logo

讨论HarmonyOS开发技术,专注于API与组件、DevEco Studio、测试、元服务和应用上架分发等。

更多推荐