知识点14:关于输入与输出

本文详细介绍了C语言中的输入输出函数,包括scanf、gets、puts、getchar和printf的使用,强调了缓冲区的影响、格式控制以及避免输入输出错误的方法,如处理空格、回车和非法字符。还讨论了这些函数在处理字符串和数字时的注意事项,特别是防止溢出攻击的重要性。
摘要由CSDN通过智能技术生成

所有输入都是先存放于缓冲区中,当按下回车(换行符也进入缓冲区中)时,告诉我们的程序:“输入暂时结束了,请去处理”,缓冲区中的数据被调用一次。

调用scanf等函数时,是从缓冲区读取。直到缓冲区内的数据读完了才等待用户再输入。

1,关于scanf

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
scanf的返回值为成功输入与格式控制符成功匹配并被读入变量的个数。如果没有数据被成功读入,返回值为0。要善于使用scanf的返回值。

  • 格式控制符中的非空白字符(逗号等)一定要和输入流中的下一个字符匹配上,如果不匹配,scanf函数会失败并且退出,之后的输入都没有读取成功。
    在这里插入图片描述

  • 如果格式控制符中含有空白字符(空格、tab、换行),则scanf会从stdin缓冲区中读入并忽略掉所有的空白字符,直到遇到一个非空白字符为止。

  • 如果格式控制字符中含有格式说明符,scanf会根据格式从stdin中读入数据,此时有3种情况被认为是数据输入结束:

    • 在stdin缓冲区中遇到空白字符
    • 遇到与格式说明符不同的非法字符输入
    • 达到输出域宽时

在这里插入图片描述
在这里插入图片描述

1,输入单个字符时

%c前有空格时scanf(" %c", &a);scanf从缓冲区中第一个非空白字符开始读取,即无论输入多少空格、回车、制表都没有用。
%c前没有空格时scanf("%c", &b);则键盘输入的都能被scanf读取(包括换行、空格、制表),相当于getchar()。
最后输入的回车也存在于缓冲区中。

2,输入数字时

空格、回车、制表 会使一次输入结束
double型浮点数只能用%lf来输入(%lf也只能用来输入double型浮点数),输出时用%f、%lf均可。总之一定要使用与数据类型对应的正确的格式修饰符 。这是因为scanf接受的只是参数的地址,必须要有正确的格式修饰符才能确定存储的格式。

3,输入字符串时

与gets不同,scanf会忽略所输入的字符串前面的空白字符,也不会读入字符串后面的空白字符,而把字符串后面的空白字符作为输入结束的标志。
scanf读取字符串时不能读取换行符。

	char str1[20], str2[20], c;
	scanf("%s", str1);
	c = getchar();//输入str1时最后的换行符仍保留在缓冲区,可以作为单个字符被直接读入 
	//但若之后接着为用scanf输入另一个字符串,则输入str1时最后的换行符不能进入字符串str2,因此str2[0]不为换行符。
	//输入的换行符会积累在缓冲区中

因此在使用完scanf后,用getchar来消化或用while(getchar()!='\n') (万能),或者在scanf中加入一个\n 即scanf("%d\n", &n);也可以在scanf之后用fflush(stdin);(这种方法不具有移植性)以清空缓冲区。

使用scanf函数时要特别注意缓冲区的问题。

	int i;
	do {
   
		printf("*");
		scanf("%d", &i);//输入a 
		if (i == 1) break;
	} while (1);
	return 0;

例如该程序,若输入a,则由于格式不匹配,scanf读取会失败,结束读入,但它不会从缓冲区中读走不匹配数据,也就是说a将一直留在缓冲区。由于缓冲区不为空,因此程序也不会停下来等待用户输入,用户也就没有机会再输入1。i没有被赋值,只是一个随机数。scanf会退出再判断再读取缓冲区再退出…程序陷入了死循环。
为了解决这个问题,我们可以利用scanf函数的返回值

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值