C语言——scanf()函数的具体详解

目录

一、两种用法

二、从scanf角度看输入

 三、格式字符串中的普通字符


一、两种用法

1.使用scanf()读取基本变量类型输入:scanf("%d",&a);

2.使用scanf()读取字符数组:scanf("%c",a[2]);

其实很好理解,使用scanf读取输入需要确定变量值的地址,因此读取基本类型输入的时候需要使用取地址符,而对于字符数组,它的首元素地址就是这个数组的地址,因此并不需要加取地址符号

说到底,scanf的参数列表是使用指向变量的指针 ,所以才涉及到变量值的地址的问题。

二、从scanf角度看输入

1.scanf的处理机制

scanf以删除的方式从缓冲区读入数据(来自标准输入设备的数据存储在缓冲区),也就是说,scanf从缓冲区读入一个数据项,该数据项在缓冲区中就被清除掉了。而如果scanf需要读取一个数据项,发现缓冲区当前是空的,那么程序就会在scanf代码处阻塞,等待用户输入,scanf函数接收到相应的数据项之后,在缓冲区中将这一数据项清除,scanf函数返回,程序继续执行。

2、scanf对不同类型输入的处理方式

希望读者记住scanf函数在读取除字符之外的输入的时候会遵守以下原则

scanf函数每次读取一个字符,跳过所有的空白字符,直到遇到第一个非空白字符的时候才开始读取。

  1.整数%d

对于整型数据的输入,也就是说"%d"类型的输入,scanf默认的分割符是所有的空白字符(空格,换行符\n、制表符以及回车\r)。也就是说如果一个scanf函数中出现scanf("%d%d",&a,&b),那么用任何一个空白字符来分隔两个整数a,b的值,变量a,b都可以接收到正确的输入。

因此对于

scanf("%d %d",&a,&b);

使用以下格式输入都是没有问题的

7    3

-》》》7 3

7

3

-》》》7 3

7        3

-》》》7 3 

 输入队列中的7和3以及中间的空格,制表符或者回车符都会被送入缓冲区,但是scanf只接受非空白字符,因此无论以上三种格式输入都不会改变输入结果,理由是scanf会跳过所有的空白字符,将其丢在缓冲区内。所以,程序在下一次读取输入的时候会首先读取到的是被丢弃在缓冲区中的空白字符,如果接下来的转换说明是%c,或者%s,将会直接读取该空白字符而不是跳过,空白字符会从打印队列中显示出来。

#include <stdio.h>
void main()
{
int a;
char c;
char b[5];
scanf("%d%c",&a,&c);
printf("a=%d c=%c",a,c);

}

 -》5          //这里的输入是5然后按下enter键(也就是换行符)

-》》》》a=5 c=

                                                                                     //这里多出来的空白一行就是输入的\n
--------------------------------
Process exited after 1.162 seconds with return value 7
请按任意键继续. . .

这里就是因为5后面的enter键被读取到c里去了,所以按下enter后还未开始输入c就已经打印了输出结果 

2.字符串%s

如果使用%s转换说明,scanf会读取除了空白以外的所有字符。

scanf在读取字符串时,在遇到第一个空白的时候会停止不再读取输入。第一个空白字符后的所有字符都会被保留在缓冲区中,直到缓冲区被刷新或者被scanf读取走。

3.字符%c

scanf在处理对字符数据的输入时,既不会忽略前导空白字符,默认也没有任何分隔字符。所有的字符,包括空白字符都会被当成输入字符。

因此如果在读取字符输入的时候一定要谨慎使用空白字符(空格、制表、换行)。

 三、格式字符串中的普通字符

这里需要明确一点

输入项和输出项的个数、顺序和类型都要与格式控制符的个数、顺序、类型严格一致

例如

scanf("%d,%d",&n,&m);

这里必须要

-》 88,121

这样按照格式化字符串里的要求:数据——逗号——数据

去输入。

由于%d会跳过所有的空白字符

所以以下的输入方式都是正确的

-》88,    121

-》88,

121

-》88  ,  121 

需要注意的是%c不会忽略空白字符

所以一旦使用%c的格式化字符串要求输入的时候

scanf("%c%c",&a,&b); 

当格式化字符串是这样要求的时候

必须按照

-》ab

的形式输入,两个字符中间不能有任何的分割符(空白字符)

因为输入的空白字符会被当做字符输出

而若格式化字符串是这样的时候

scanf("%c %c",&a,&b);

这样我们正常输入就可以了,因为我们不管是输入

-》a b

-》a

b

-》ab

 都会正常输出

这是因为%c %c中间的这个空格(或者tab键输入的制表符,或者换行符),都是用来屏蔽空白符的。%c前没空格,scanf()将读取缓冲区中的第一个字符,%c前有空格,scanf()则读取缓冲区中第一个非空白字符。

因为正常输入后a字符被第一个%c读取,赋值给变量a,而此时来到了两个%c中间的空格,这个空白字符意味着在输入两个字符之间输入的任何空白字符都将被忽略,因此除非键入第二个非空白字符结束输入,否则输入会阻塞在这里。

这同样对%d以及其他格式化输入适用

在scanf中 格式字符串中出现的空白符不是表示接受一个空白符,而是表示忽略所有的空白字符(包括回车,空格,tab )。所以想要结束输入,输入任意一个非空白字符即可,但是该字符仍然会留在缓冲区中。
#include <stdio.h>
int select(int a, int b)
{
	if (a > b)
		return a;
	else if (a < b)
		return b;
	else
		return a||b;
}
int main()
{
	printf_s("Please input two intergrites:");
	int a, b,Max;
	scanf("%d%d\n", &a, &b);
	Max=select(a, b);
	printf("%d", Max);
	return 0;
}

 运行这段代码,结果是这样的

为什么会这样呢?其实在格式字符串中,写入了一个‘\n’,而在格式字符串中出现了空白符(空格,换行,制表)都意味着我们在输入中将忽略(跳过)一切的空白符,因此,当我们输入10和5后,现在第一个%d和第二个%d都已经正常读取了,但是其中的\n意味着将从此开始忽略以后键入的所有空白字符,因此还需要输入任意一个字符去结束输入,除非这时候键入一个非空白字符,否则按下多少enter(注意enter键输入的是换行符)都没办法结束输入。 

总结:

scanf在读取输入的时候,分为多种情况:

一、读取字符串的时候(%s)

        scanf会读取除了空白字符以外的所有字符,并在读取到第一个空白字符时结束读取,将空白字符之后的所有字符都暂存在缓冲区中。除非缓冲区被刷新或者字符被读取走,否则将一直停留在缓冲区中。

二、读取字符的时候(%c )

        scanf会读取所有字符包括空白字符。但是他会在读取到第一个空白字符后结束读取。将空白字符之后的所有字符都暂存在缓冲区中。

三、读取除了字符和字符串以外的所有输入的时候

        scanf函数每次读取一个字符,跳过所有的空白字符,直到遇到第一个非空白字符的时候才开始读取。

        

此外,我们一旦在scanf的格式化字符串中写入了空白字符后,就意味着告诉scanf,我键入的所有空白字符都会失效。当输入非空白字符时才开始读取

scanf("  %c%c",&a,&b)
printf("a=%c,b=%c", a, b);

//此时无论先输入多少个空白字符,都不会被读取,当读取到第一个非空白字符的时候,scanf认为开始读取了,接下来读取到的所有字符都有效
//输入一个空格和ab
>>> ab
>>>a=a,b=b
--------------------------------
Process exited after 1.876 seconds with return value 0
请按任意键继续. . .
//输入ab
>>>ab
>>>a=a,b=b
--------------------------------
Process exited after 1.876 seconds with return value 0
请按任意键继续. . .
//输入空格和a和按下enter
>>> a
>>>a=a,b=

--------------------------------
Process exited after 2.229 seconds with return value 0
请按任意键继续. . .
这里b赋值为换行符

        scanf确实是c语言里一个比较细节的点,以及读者需要分清scanf函数和scanf_s函数,这两个函数虽然看起来相似但是细节上还是有不同的,一个是传统的c语言标准输入函数,一个是后期Visual studio有且仅支持的scanf_s函数。读者需要将其区分开来,此外,读者还应该将回车符和换行符区分开来,回车符是\r,换行符是\n。enter键我们称为回车键但是输入到C中其实是换行符。

  • 8
    点赞
  • 33
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
scanf函数C语言中用于从标准输入(键盘)读取数据的函数。它的基本用法是通过格式化字符串指定输入数据的类型和格式,并将读取到的数据存储到相应的变量中。 scanf函数的格式如下: ```c scanf("格式控制字符串", 参数列表); ``` 其中,格式控制字符串用于指定输入数据的类型和格式,参数列表是一系列变量,用于接收输入数据。下面是一些常用的格式控制字符串及其对应的数据类型: - %d:读取整数 - %f:读取浮点数 - %s:读取字符串 - %c:读取单个字符 例如,如果要从键盘读取一个整数并存储到变量num中,可以使用如下代码: ```c int num; scanf("%d", &num); ``` 注意,在读取整数时,需要使用取地址符`&`来获取变量num的地址,以便将输入数据存储到该地址中。 另外,scanf函数可以一次读取多个数据,并且可以根据需要使用多个格式控制字符串和参数。例如,如果要从键盘读取两个整数并存储到变量num1和num2中,可以使用如下代码: ```c int num1, num2; scanf("%d %d", &num1, &num2); ``` 在这个例子中,两个整数之间用空格分隔。 需要注意的是,scanf函数在读取数据时遇到空白字符(空格、制表符、换行符)时会停止读取,并且不会自动跳过空白字符。因此,在读取多个数据时,需要确保格式控制字符串中的空白字符与输入数据相匹配。 此外,scanf函数还可以进行一些其他的功能,如跳过输入数据、限制输入数据的长度等。具体的用法可以参考C语言的相关文档或教程。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值