scanf()使用注意事项(C语言)


以下是对scanf()函数的总结,有些部分来源于C Primer Plus。

scanf()的优势:
相比于其他的接收输入的函数,getchar()接收单个字符,get()和fget()只能接收字符串,而scanf()能接收混合格式的输入。
scanf()的劣势:
C编译器不会检查引号中格式说明符的是否匹配后面的参数

空白字符

1.除了%c,对于其他的所有格式说明符,scanf()会跳过所有空白字符(包括空格、制表符、换行符)
2.举个例子,输入-13.45e12# 0

	scanf("%d", &ch);
	printf("%d", ch);

在这里插入图片描述
scanf()首先会跳过缓冲区中的任何空白字符,随后遇到负号-。
而格式说明符%d的含义是将输入解释成有符号的十进制整数,于是scanf找到了一个负号 - ,保存该字符,然后读取下一个字符,如果下一个字符是数字,保存该字符并读取下一个字符。
当遇到一个非数字字符,它会认为已经读到了整数的末尾。然后scanf()会把这个字符放回到输入。程序在下一次读取输入的时候,首先会读取到上一次读取丢弃的字符小数点 ‘.’ 。

3.如果scanf()中有多个%d,那么当第一个%d丢弃小数点后会发生什么情况呢

	scanf("%d%d", &ch1, &ch2);
	printf("ch1=%d, ch2=%d", ch1, ch2);

在这里插入图片描述
书中说到,C规定在第一个出错处停止读取输入,也就是说其他变量的读取会一直卡在小数点这个地方。之后发生了什么我不太清楚,总之除了第一个ch1,后面的变量的值都不是期望得到的值。
再给一个更多变量的例子

	scanf("%d%d%d%d", &ch1, &ch2, &ch3, &ch4);
	printf("ch1=%d, ch2=%d, ch3=%d, ch4=%d", ch1, ch2, ch3, ch4);

在这里插入图片描述

%s

scanf()会把跳过所有空白,读取-13.45e12#,而空格会留在输入中,作为下一次输入的首字符。
如果用字符数组存储字符串-13.45e12#,scanf()会在字符串末尾自动加上空字符 ‘\0’ ,所以在计算字符数组的时候记得算上‘\0’的位置

5.再来看一种情况,看下scanf()在有字段宽度的%s中,是否会读取字符串之间的空格

	char ch1[20]={'a'}, ch2[20]={'a'};
	scanf("%12s", ch1, ch2);
	printf("\nch1=%s\n", ch1);
	printf("ch2=%s\n", ch2);

在这里插入图片描述
可以看到,无法通过指定字段宽度,来实现跳过字符串之间的空格

%c

scanf()会读取当前输入中还剩下的第一个字符,无论这个字符是什么
因此,如果想跳过字符前的空格,或是换行符,常使用getchar()来跳过字符
另外,还有进阶的玩法,在%c前添加空格或是换行符,此时scanf()会跳过所 有的空格(换行符)

char ch={'a'};
	scanf("\n%c", &ch);
	printf("\nch=%c\n", ch);

在这里插入图片描述
没有加\n的情况,输入“\n66”

	char ch={'a'};
	scanf("%c", &ch);
	printf("\nch=%c\n", ch);
	//printf("ch2=%s\n", ch2);	

在这里插入图片描述

缓冲区

以下直接摘录一段书中的话
回显用户输入的字符后立即重复打印该字符是属于无缓冲输入,即正在等待的程序可立即使用输入的字符。
在用户在用户按下Enter前不会重复打印刚输入的字符,这种输入形式属于缓冲输入。用户输入的字符被收集并存储在一个被称为缓冲区的临时存储区。
ANSI C规定输入是缓冲的。
缓冲分两类。完全缓冲I/O,常见于文件输入,指缓冲区被填满时才刷新缓冲区。行缓冲I/O,指出现换行符时刷新缓冲区。

添加普通字符

最近才发现,在格式字符串中输入任意普通字符,scanf()会跳过这个字符,接收该字符后面的内容

	scanf("_%c", &ch);
	printf("\nch=%c\n", ch);

在这里插入图片描述
但是这个只能跳过一次

	char ch[10];
	scanf("/%s", ch);
	printf("\nch=%s\n", ch);

在这里插入图片描述
前面说的空格、换行符、制表符除外,对于它们,C会跳过所有的空白字符(对于%c也一样)
此外,符号 / 也除外

	char ch;
	scanf(" %c", &ch);
	printf("\nch=%c\n", ch);

在这里插入图片描述

符号*

把*放在%和转换字符之间,会使scanf()跳过相应的输出项

	char ch;
	scanf("%*d%c", &ch);
	printf("\nch=%c\n", ch);

在这里插入图片描述
如果觉得有帮助,还请随手点个赞吧~

  • 6
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值