Scanf函数攻略:

(A)                格式化说明符
格式字符          
说明

%d                 读入十进制整数

%u                
读入一个无符号十进制整数

%lld                   
长整型

%I64d               
64位整形

%f                
读入一个浮点数float

%lf                     
读入一个浮点数double

%o                 读入八进制整数
%x                 读入十六进制整数
%X                 同上

%c                 读入一个字符
%s                 读入一个字符串

%[]                扫描字符集合
%%                 读%符号
                
附加格式说明字符表

修饰符                      
说明

L/l 长度修饰符              
输入"长"数据
h 长度修饰符                
输入"短"数据
W 整型常数                  
指定输入数据所占宽度
* 星号                      
空读一个数据 
(B)        
空白字符

空白字符会使scanf()函数在读操作中略去输入中的一个或多个空白字符,空白符可以是space,tab,newline等等,直到第一个非空白符出现为止。

#include<stdio.h>

int main(){

char a,b,c;

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

printf("%c,%c,%c\n",a,b,c);

return 0;

}

#include<stdio.h>

int main(){

int a;

scanf("%d\n",&a); );//这里多了一个换行符’\n’

printf("%d\n",a);

return 0;

}

结果要输入两个数程序才结束,而不是预期的一个。why?

原因:用空白符结尾时,scanf会跳过空白符去读下一个字符,所以你必须再输入一个数。这里的空白符包括:
空格,制表符,换行符,回车符和换页符。所以如果你用scanf( "%d ",&a)也会出现同样的问题。 
解决方法:自己平时注意。当出现这样的问题的时候,可以检查一下代码。

(C)       
非空白字符

一个非空白字符会使scanf()函数在读入时剔除掉与这个非空白字符相同的字符。

#include<stdio.h>

int main(){

int a,b,c;

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

printf("%d,%d,%d\n",a,b,c);

return 0;

}

运行时按如下方式输入三个值:

3,4,5 ↙(输入a,b,c的值)

或者

3,□4,□5 ↙(输入a,b,c的值)

3,□□□4,□5 ↙(输入a,b,c的值)
......

都是合法的,但是","一定要跟在数字后面,如:
3□,4,5 ↙就非法了,程序出错。(解决方法与原因后面讲)

问题探讨:

问题1 
scanf()函数不能正确接受有空格的字符串?如: i love you

#include<stdio.h>

int main(){

char s[50];

scanf("%s",s);

printf("%s\n",s);

return 0;

}

解决:

#include<stdio.h>

int main(){

char s[50];

/*scanf("%s",s);不能接收空格符*/

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

printf("%s\n",s);

return 0;

}

问题2
单个字符char
吸收空格、回车

#include<stdio.h>

int main(){

int a;

char c;

scanf("%d",&a);

scanf("%c",&c);

printf("%d %c\n",a,c);

return 0;

}

原因:c吸收了回车

解决1:处理掉回车

#include<stdio.h>

int main(){

int a;

char c;

scanf("%d",&a);

getchar();//吸收回车 //或者 fflush(stdin);//清除一个流

scanf("%c",&c);

printf("%d %c\n",a,c);

return 0;

}

解决2:使用“空白字符”屏蔽回车

#include<stdio.h>

int main(){

int a;

char c;

scanf("%d",&a);

scanf(" %c",&c);//注意%c前有个空格

printf("%d %c\n",a,c);

return 0;

}

问题3 
如何处理scanf()函数误输入造成程序死锁或出错?

#include<stdio.h>

int main(){

int a,b,c; /*计算a+b*/

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

c=a+b;

printf("%d+%d=%d\n",a,b,c);

return 0;

}

如果输入了错误的类型,你的程序不是死锁,就是得到一个错误的结果。

解决方法:利用scanf()函数执行成功时的返回值是成功读取的变量数。但这里还要注意另一个问题,如果输入了非法数据,键盘缓冲区就可能还个有残余信息问题。

#include<stdio.h>

int main(){

int a,b,c; /*计算a+b*/

while(scanf("%d%d",&a,&b)!=2)fflush(stdin);

c=a+b;

printf("%d+%d=%d\n",a,b,c);

return 0;

}

问题4 scanf()函数的参数输入类型不匹配问题

#include<stdio.h>

int main(){

int a=123;

char c='t';

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

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

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

printf("%d\n%c\n",a,c);

return 0;

}

当输入a 回车后,会直接跳过下面2个scanf语句,直接输出为 
123 
t

原因:对于scanf( "%d%c ",&a,&c),scanf语句执行时,首先试图从缓冲区中读入一个%d类型的数据,如果和 第一个参数匹配,则继续从缓冲区中读取数据和第二个参数进行匹配,依次进行下去,直到匹配完所有的参 数;如果其中有一个参数不匹配,那就从这个地方跳出,忽略这个scanf后面所有的参数,而去执行下一条语 句。

可以用下面的程序验证一下:

#include<stdio.h>

int main(){

int a=0,b=0;

char c='a';

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

scanf(" %c",&c); //%c前加空格,屏蔽回车

printf("%d\n%d\n%c\n",a,b,c);

return 0;

}

输入: 3 a

输出:

3

0

a

解决:同 
问题3

#include<stdio.h>

int main(){

int a=0,b=0;

char c='a';

while(scanf("%d%d",&a,&b)!=2)fflush(stdin);

scanf(" %c",&c);//%c前加空格,屏蔽回车

printf("%d\n%d\n%c\n",a,b,c);

return 0;

}

只有输入正确数据,例如:

100 100

a

时,才出结果。

补充:扫描集[...]和补集[ ^...]

扫描集[...]

#include<stdio.h>

int main(){

char s[100];

scanf("%[1234567890]",s);

printf("%s\n",s);

return 0;

}

通过运行可以发现它的作用是:如果输入的字符属于方括号内字符串中某个字符,那么就提取该字符;如果 一经发现不属于就结束提取。该方法会自动加上一个字符串结束符到已经提取的字符后面。

注意:a方括号两边如果有空格,如:scanf( "%[ 1234567890 ] ",strings);
那么空格也会算在里面的,即可以提取空格。

b对于许多实现来说,用连字符可以说明一个范围。例如,以下扫描集使 scanf()
接受字母 A
到Z:%[A-Z]

补集[ ^...]

用字符 ^ 可以说明补集。把 ^
字符放为扫描集的第一字符时,构成其它字符组成的命令的补集合,指示 scanf()
只接受未说明的其它字符。

scanf("%[^1234567890]",s); 它的作用是:如果一经发现输入的字符属于方括号内字符串中某个字符 ,那么就结束提取;如果不属于就提取该字符。该方法会自动加上一个字符串结束符到已经提取的字符后面 。

用这种方法还可以解决一般的scanf的输入中不能有空格的问题。

只要用 scanf("%[^\n]",s);
就可以了。

scanf()函数的更多相关文章

  1. 4-printf & scanf函数

    一.printf函数 这是(printf和scanf)在stdio.h中声明的一个函数,因此使用前必须加入#include <stdio.h> 1.用法 1> printf(字符串) ...

  2. C语言scanf函数详细解释

    原文链接 函数名: scanf 功 能: 执行格式化输入 用 法: int scanf(char *format[,argument,...]); scanf()函数是通用终端格式化输入函数,它从标准 ...

  3. 黑马程序员-scanf函数

    变量的内存:字节和地址:1.变量的存储单位是字节,每个字节都有存储地址.2.不同的数据大小占用的内存带下不同拥有的字节数也是不同的.变量的存储:1.存储是按照,先存储的放在地址教高的位置,优先存储的地 ...

  4. C语言Scanf函数

    C语言的scanf函数 一.变量的内存分析 (一)字节与地址 ①. 内存以字节为单位 每个字节都有自己的内存地址,根据地址就可以找到该字节.整个内存相当于一整个酒店,而酒店以房间为单位,在这里每个房间 ...

  5. scanf函数

    一. 变量的内存分析 1. 字节和地址 为了更好地理解变量在内存中的存储细节,先来认识一下内存中的“字节”和“地址”. 1> 内存以“字节为单位” 0x表示的是十六进制,不用过于纠结,能看懂这些 ...

  6. scanf函数与输入缓冲区

    本文链接:http://www.cnblogs.com/xxNote/p/4008668.html 今天看书的时候遇到scanf函数与缓冲区的问题,产生了一些猜想即:应该有一个指针来记录缓冲区中读取到 ...

  7. Scanf函数输入字符串

    Scanf函数输入字符串 #define _CRT_SECURE_NO_WARNINGS //#pragma warning(disable:4996) #include <stdio.h> ...

  8. [转载]VS2012编译C语言scanf函数error的解决方法

    在VS 2012 中编译 C 语言项目,如果使用了 scanf 函数,编译时便会提示如下错误: error C4996: 'scanf': This function or variable may ...

  9. 【C语言】05-printf和scanf函数

    一.printf函数 这是在stdio.h中声明的一个函数,因此使用前必须加入#include <stdio.h>,使用它可以向标准输出设备(比如屏幕)输出数据 1.用法 1> pr ...

  10. 黑马程序员——C语言基础 scanf函数 基本运算 三目运算符

    Java培训.Android培训.iOS培训..Net培训.期待与您交流! (一下内容是对黑马苹果入学视频的个人知识点总结) (一)scanf函数 1>  简单介绍一下scanf函数   这是在 ...

随机推荐

  1. Hibernate 3 深度解析--苏春波

    Hibernate 3 深度解析   Hibernate 作为 Java ORM 模式的优秀开源实现, 当下已经成为一种标准,为饱受 JDBC 折磨的 Java 开发者带来了“福音.快速的版本更新,想 ...

  2. Java HashMap学习笔记

    1.HashMap数据结构 在java编程语言中,最基本的结构就是两种,一个是数组,另外一个是模拟指针(引用),所有的数据结构都可以用这两个基本结构来构造的,HashMap也不例外.HashMap实际 ...

  3. log4net报错Could not load type 'System.Security.Claims.ClaimsIdentity'

    使用log4net,在win7上可以正常使用,但是在部分xp电脑上可以生成access数据库,但是无法写数据到mdb 排除了程序原因,怀疑是xp缺少什么dll之类的 偶然查到log4net的调试方法: ...

  4. sql的一些知识_order by

    注释 SELECT name FROM userinfo #这是注释 /* 这是多行注释 */ order by 排序() SELECT username FROM userinfo ORDER BY ...

  5. Food hub

    Work center List Tillage 耕作 Hand harvest 手工采收 Planting 种植 Cultivating 培养 Mulching 覆盖 Dig harvest 挖地采 ...

  6. C#文件操作与编程

    一:驱动器System.IO 软盘,优盘,光盘,硬盘 DriveInfo/DriveType DriveInfo:确定有关驱动器的信息:盘符,类型,可用空间 DriveType:确定DriveInfo ...

  7. hdu5318 The Goddess Of The Moon (矩阵高速幂优化dp)

    题目:pid=5318">http://acm.hdu.edu.cn/showproblem.php?pid=5318 题意:给定n个数字串和整数m,规定若数字串s1的后缀和数字串s2 ...

  8. C++ &quot;#&quot;的作用和使用方法

    本系列文章由 @yhl_leo 出品,转载请注明出处. 文章链接: http://blog.csdn.net/yhl_leo/article/details/48879093 1 #和##的作用和使用 ...

  9. kubernetes资源调度之LimitRange

    系列目录 LimitRange从字面意义上来看就是对范围进行限制,实际上是对cpu和内存资源使用范围的限制 前面我们讲到过资源配额,资源配额是对整个名称空间的资源的总限制,是从整体上来限制的,而Lim ...

  10. 开源流媒体服务器EasyDarwin支持epoll网络模型,大大提升流媒体服务器网络并发性能

    经过春节前后将近2个月的开发和稳定调试.测试,EasyDarwin开源流媒体服务器终于成功将底层select网络模型修改优化成epoll网络模型,将EasyDarwin流媒体服务器在网络处理的效率上提 ...