scanf函数、getchar函数、gets函数等函数的误区(回车输出问题)

文章详细探讨了C语言中scanf函数、getchar函数和gets函数的运行原理,指出它们并不与键盘输入同步,而是从输入缓冲区读取。通过代码示例解释了如何处理换行符( )的问题,提出了两种解决方案:在格式字符串中添加 或使用getchar函数清空缓冲区。此外,还特别提到了%s处理字符串时不会读取回车的情况。
摘要由CSDN通过智能技术生成

目录

一、运行原理

二、从代码角度观察

三、总结

四、那怎么解决这种情况呢

(1)、方法一

(2)、方法二

 五、补充


一、运行原理

scanf函数、getchar函数、gets函数等这类函数是这样的运行的:

 可以看出来,scanf函数并不是键盘按什么,就读取什么,换种说法是键盘输入和函数读取不是同步的,而是从键盘输入后,会先保存到输入缓冲区,然后函数从输入缓冲区读取输入进缓冲区内的内容。

二、从代码角度观察

#include<stdio.h>
int main()
{
	char ch[3] = { 0 };
	int i = 3;
	int j = 0;
	while (i--)
	{
		scanf("%c", &ch[j++]);
		
	}
	if (ch[1] == 'a')printf("ok");
	return 0;
}

●上述代码的意思是,输入三次,分别保存到字符型数组中,如果第二次输入的是a则会输出ok,我们现在来运行这段代码,看看结果:

 

 

本来的想法是输入'd'按确认键表示第一次输入结束,紧接着输入'a'按确认键,然后输入第三个字符,可是当第二次输入a按确认键后程序运行结束了,可以看出来的是,此时ch[1]是'\n',ch[2]是'a',跟我们最初想的每次输入一个字符,输入三次的预想结果完全不一样。

●比较一下下面这个代码,运行如下:

#include<stdio.h>
int main()
{
	char ch[3] = { 0 };
	int i = 3;
	int j = 0;
	while (i--)
	{
		scanf("%c", &ch[j++]);
		
	}
	if (ch[1] == '\n')printf("ok");
	return 0;
}

 

可以看出来它输出了ok。ch[0]、ch[1]、ch[2]的值分别是a、\n、d。

●再来运行这段代码:

#include<stdio.h>
int main()
{
	char ch;
	while (1)
	{
		scanf("%c", &ch);
		printf("%c", ch);
	}
	return 0;
}

你先猜一下会是怎么运行的呢 ????☕

 第一次运行只输入了a然后按下确认,可以看到输出了a,并将光标移动到下一行开始,所以其实是while循环运行了两次,第一次从输入缓冲区读取到a,然后输出a,第二次从缓冲区读取'\n',然后输出。

 第二次运行,在屏幕上输入了a、b、c、d、e、f、g、h按下确定键,此时缓冲区中是a、b、c、d、e、f、g、h、'\n'然后scanf函数读取到的也是a、b、c、d、e、f、g、h、'\n',所以光标会到下一行开始位置,说明scanf读取了'\n',printf函数将其输出。

三、总结

键盘先输入到输入缓冲区,当识别到程序员按下确认键,scanf函数便会开始从输入缓冲区读取内容。最开始笔者认为键盘输入的时候scanf函数就同步读取内容,当按下确认键后,scanf函数暂停读取输入的内容,如果这样理解正确的话,就不会像上面运行的结果那样输出一个“换行符”,使得光标移动到下一行开始位置,ch[1]里面也不会保存成'\n'。

所以总结一下就是,输入型函数的运行过程是,程序员先从键盘输入到输入缓冲区,当识别到按下确认键后,函数开始从缓冲区读取内容。

四、那怎么解决这种情况呢

(1)、方法一

在%c前面加个\n,变成scanf("\n%c",&ch),首先\n在这里会匹配到缓冲区中0个或多个\n,当scanf函数中的\n匹配到了输入缓冲区的\n,scanf把\n获取后直接扔了,\n不会被赋给任何变量,然后我们再输入一个字符,被%c获取并赋值给ch变量。

#include<stdio.h>
int main()
{
	char ch;
	while (1)
	{
		scanf("\n%c", &ch);
		printf("%c", ch);
	}
	return 0;
}

可以看出来,光标没有换到第二行,也就是没有读到'\n',没有将回车赋值给ch变量。就解决了\n在输入过程中的乱换行问题。

(2)、方法二

对于数字%d,%f,字符串%s等等这个\n就影响不大了,当然也可以用在格式符前面加\n来清除缓存,但是通常会用如下方法,来解决这一问题:

#include <stdio.h>
 
int main()
{
	int  a;
	while(1){
		scanf("\n %d",&a);
		printf("%d\n",a);
		while('\n' != getchar()){//清空缓冲
			continue;
		}
	}
	return 0;
}

 五、补充

这里单独补充%s的一些内容

#include<stdio.h>
int main()
{
	char ch[20] = { 0 };
	scanf("%s", ch);
	printf("%s", ch);
	return 0;
}

当按下确认键后可以看出来输出完字符串后光标没有移动到下一行,也就是没有读取到输入缓冲区中的'\n',这是因为%s 是从输入流中读取一个字符串,输入流中字符串以空白(空格,tab, 回车换行) 为分隔, 所以读得的字符串不含回车。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

故里♡9513

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值