C语言学习day5-scanf循环读取

1.地址内存原理解析
CPU通过地址总线(32位有32根线,对应8字节32个数的地址)去内存里要数据
然后内存收到请求之后,根据收到的地址查找对应得数据,
再通过32位的数据总线把得到的数据再传回CPU。

2.scanf循环读取
发生错误时返回EOF
3.什么是EOF?
直接在代码中输入EOF,按着CTRL,鼠标左键点击,原来EOF就是-1

4.什么情况下scanf会出错?
行首输入ctrl z,回车
行首输入ctrl z,回车
行首输入ctrl z,回车
VS 2019需要按3次组合键Ctrl+Z才能让scanf函数出错返回-1

5.插曲解析一下为什么scanf输入某一个值,与scanf中设定的值不匹的时候陷入死循环的原因

当我们在运行如下代码的时候

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>

int main()
{
	int i,ret;
	while ((ret=scanf("%d", &i))!=EOF) //while是实现循环,后面要有一个小括号
	{		
		printf("i=%d\n", i);
	}
	return 0;
}

正常应该是像下图这样,输入一个数回车,输出一个数;如此反复。

C语言学习day5-scanf循环读取

但是当我们不按要求输入整型数,而输入一个字母"a",会得到如下图结果,会一直疯狂地不停地打印i=10,那么这是为什么呢?这就可以用之前学到的scanf存在的一个标准输入缓冲区来解释,程序执行之后,我们首先输入10,敲回车('\n'),10'\n'会存入到标准输入缓冲区,此时scanf根据"%d",拿到10这一值后,输出i=10,此时缓冲区里还剩一个'\n',所以不会卡住让你在黑框中输入东西,会继续执行scanf,而执行scanf的时候"%d"会先把留在缓冲区的那个'\n'清除掉,此时缓冲区为空,会卡住让你输入值,当我们继续正常输入数字的时候,会如上图那样正常输入输出,但此时我们输入"a",敲回车('\n'),这个时候a'\n'会被存在标准输入缓冲区中,此时scanf根据"%d"进行取值,但是首先匹配到的是一个"a",跟"%d"不匹配,scanf返回值理论上是匹配值成功的数量,但此时没有一个值与"%d"匹配,所以返回一个0,0!=EOF(-1),所以会重复的执行While语句,不断地打印,每次执行的时候虽然都会重新匹配,但a'\n'会一直留存在缓冲区不会被清理掉(只有单单留存一个'\n'的时候才会被%d,%f等清理掉),所以一重循环往复的匹配失败返回0,就一直重复执行printf打印i=10(因为i没有被重新赋予值,所以一直是10),如此陷入死循环。

C语言学习day5-scanf循环读取

那么如何解决上述问题呢?

 这就需要我们在循环完一次之后通过某一个方法清除掉缓冲区中残存的数据,使用VS就要借用的一些接口,VS2012用的是fflush(stdin),VS2013-2019用的是rewind(stdin),即把代码改成如下形式,在标注块加一个rewind(stdin)

C语言学习day5-scanf循环读取

以下是执行结果,可以看到在输入a之后,只是重复输出了一次i=10,代码就又可以继续正常执行了。

C语言学习day5-scanf循环读取

6.以下代码是循环读取字符操作,用于循环读取一串字母之后改成,把其由小写改为大写(一般循环读取字母不清理缓冲区)

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>

int main()
{
	char c;
	while (scanf("%c", &c) != EOF)
	{
		if (c != '\n')//判断,后面有一个小括号,小括号里面是一个表达式
		{
			printf("%c", c - 32);
		}
		else
		{
			printf("\n");
		}
	}
}

在运行代码的时候遇到了这样一个报错"错误 1error LNK1207 PDB 格式不兼容;请删除并重新生成",经过查阅相关资料之后得出,只需按指定路径将这个PDB文件删除之后重新运行就可以完美解决;但是并没有弄明白这个PDB文件是什么,留存一个疑问,以后解决。

以下是执行结果

C语言学习day5-scanf循环读取

7.scanf的混合输入

当我们执行以下代码的时候,用一个scanf读取混合输入的多个数值的时候,需要在%c前加入一个空格,否则"%c"会把输入值的时候例如"1001 m 98.5","1001"后面的那个空格读取进去。

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>

//一个scanf读多种类型的数据
//混合输入时每次在%c之前需要加入一个空格
int main()
{
	int i;
	char c;
	float f;
	int ret;
	ret=scanf("%d %c%f", &i, &c, &f);
	printf("i=%d,c=%c,f=%f\n", i, c, f);
	return 0;
}

上一篇:day5 crm客户管理权限控制代码优化


下一篇:冲刺day5