scanf()函数总结

基本说明


  • 功能: 按用户指定的格式从键盘上把数据输入到指定的变量之中。
  • 头文件:#include <stdio.h>
  • 标准格式:scanf("<控制串>",变量地址) 输入一个整数:scanf("%d",&a);
  • 返回值:scanf()函数返回成功赋值的数据项数,读到文件末尾出错时则返回EOF。(后面详解)

实例


返回值
scanf函数就是返回正确输入的数据个数,返回值int型,以下代码说明:

#include <stdio.h>
int main()
{
    int a,b,c;
    c=scanf("%d%d",&a,&b);
    printf("%d",c);
}
输入输出
1 22
1 a1
a b0

如果遇到错误或遇到end of file,返回值为EOF,所以经常见到

while(scanf("%d",&a)!=EOF)

控制串说明


控制串有三种类型:格式说明符(也是最常用的)、空白符,非空白符

1.经常使用的格式说明符就不多说了,比如输入一个整数一个字符

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

比如键入 1x 那么就将1赋值给变量a 将’x’赋值给变量c。


2.空白符


空白字符会使scanf()函数在读操作中略去输入中的一个或多个空白字符。
其中空白字符包括space,tab,newline等等。比如

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

若输入10 20 则就将10赋给a ,20 赋给b , 输入时候的空格则忽略;
注:如果格式是字符 char的话,空格或者转义字符会被当做普通字符:

int a;char c;
scanf("%d%c",&a,&c);
printf("%d%c",a,c);

若输入10 a 输出将会是10 而不是10 a 这是因为空格赋值给了c
'a' 则继续留在缓冲区内,如果再下面再加一句scanf("%c",&c) (不用再次输入),那么此时c的值就是'a'
本质上,控制串中的空白符使 scanf() 在输入流中读,但不保存结果,直到发现非空白字符为止。

3.非空白符[过滤]


非空白字符会使scanf()函数在读入时剔除掉与这个非空白字符相同的字符;这个在实际应用中挺常用的;
1,比如我想输入的字符串是’a=2 b=3’,而且还需要将a,b赋值成2,3,,可以这样实现。

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

这样输入的时候直接输入a=2b=3 scanf()就会自动剔除掉不需要的字符,而将2赋值给a,3赋值给b
这里空格space,同样可以使用

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

这样同样可以实现空格输入:输入10 20 同,space将相当于一个普通字符。
2, 宽度设置
在百分号(%)与格式码之间的整数用于限制从对应域读入的最大字符数。例如,希望向name 读入不多于 10个字符时,可以书写成如下形式:

scanf("%10s",name);

如果输入流的内容多于 10 个字符,则下次 scanf() 从此次停止处开始读入。 若达到最大域宽前已遇到空白符,则对该域的读立即停止;此时,scanf() 跳到下一个域。

3,省略指定的数据类型*符号
比如

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

比如输入10a20,得到的是a=10,b=20
再如

char c[20];
scanf("%*s%s",&c);
printf("%s",c);

若输入"hello, world" 则会输出world 因为world之前的space终止了%*s.
注:%是选择满足条件的,%* 是过滤掉满足条件的。可以配合下面所说的扫描集使用。


4.scanf的”正则表达式”—扫描集
扫描集定义一个字符集合,可由 scanf() 读入其中允许的字符并赋给对应字符数组。 扫描集合由一对方括号中的一串字符定义,左方括号前必须缀以百分号。
遇到不属于扫描集的结束;有点像正则表达式,其实用法也很类似。
比如 :

char s[10];
scanf("%[abc]",s);
输入输出
abcabc
bcbc
abdfab
abdcbab

就类似一个过滤。
下面是一些常用符号:
- ^表示补集: %[^abc] 遇到abc停止
- ‘-‘表示区间: %[A-Z] A-Z范围
- %[^\n] 表示可以吸收空格,回车结束;

char s[10];
scanf("%s",s);
printf("%s",s);

比如输入的是'I love you'那么输出的s 是I, 而不是I love you
因为空格作为了分隔符。
而想要吸收空格可以用 扫描集

char s[10];
scanf("%[^\n]",s);
printf("%s",s);

表示只有输入回车才结束
此时再输入 I love you 将完整输出 I love you

再看一个例子:
要去出一个邮箱的域名,经常用正则,那么这里用scanf的该怎么使用呢?

char s[30];
scanf("%*[^@]@%[^\.]",s);
printf("%s",s);

这个可以 输入mymail@gmail.com 输出就会是 gmail;
首先分成三部分%*[^@]@%[^\.] ;
%*[^@] 表示过滤前面的不是@的部分,这部分读取到了mymail 但是不保存到变量 s。第二部分@ 是指过滤掉 缓存区中的 @ 字符。 最后一部分%[^\.] 则表示选择不是.的部分,对应字符串中的gmail部分,并且赋值给s。
注:
1. 在scanf()正则里面 最多只能有一个%表示选择。而过滤%*可以有多个
2. 上述所讲的正则规则 与sscanf()函数完全适用。只不过是输入方式不同。
其实 scanf()用正则比较少。sscanf()就比较常用了。很方便的处理字符串。


5.scanf()缓冲区问题总结

int a;
char c;
scanf("%d",&a);
scanf("%c",&c);
printf("a=%d  c=%c",a,c);

比如输入20 a 那么输出将会是 20和一个空格[前面已经提到过]
如果打算想 输入20之后 回车再输入’a’ 结果会是输入回车之后 就会输出。这时候如果输入c的ASCII码值就会发现是 10 正好是\n
这样就对了,\n被scanf()函数“错误”地赋给了c;
常见的解决方法:
1. 在第一个scanf()之后加入getchar()函数可以消掉回车。具体原理还不太懂。。
2. 还有就是利用fflush(stdin); 刷新或者清空缓冲区,这样输入一个20之后 按回车的话就可以,继续输入字符 赋值给c,如下:

#include <stdio.h>
int main()
{
    int a,b;
    char c;
    scanf("%d",&a);
    fflush(stdin);
    scanf("%c",&c);
    printf("a=%d c=%d\n",a,c);
}

这样就可以了。

上面是学了以scanf的一些总结, 虽然平时使用的很简单,但是总感觉不太踏实,因为总时不时的出错。这次记录一下学习收获挺大的。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值