scanf语句执行过程:

(1)逆序取参数的偏移地址并分别入栈。

(2)根据控制字符串的格式说明符从缓冲区取数据给各变量赋值。

①若格式说明符是数值类数据:如果从缓冲区中拿出的第一个字符可以合法表示该数值类型数据(如对应%d的可以是任何数字字符、+、-;若对应%x,则除了以上还有字母a—b也可,and so forth...),然后取下一个字符,直到非合法字符,则认为该数值读取完毕并把该非法字符送回缓冲区。把之前取得的合法字符串转换成相应的数值类型并赋值。

如果从缓冲区中拿出的第一个字符对应格式说明符来说不是合法字符则直接把该非法字符送回缓冲区,在不给当前变量赋值的情况下结束该条语句。如:

 #include<stdio.h>
int main ( )
{
int a,i=;
printf("%d\n",a);
while(i<)
{scanf("%d",&a);
printf("%d\n",a);
i++;
}
return ;
}

程序执行如下图(其中第2行的a为输入回显)

aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAAAQIAAACHCAIAAAByJ8DYAAAD6UlEQVR4nO3d23XjNhQF0NNuukopqiJpYBpIKsiHlWUOH5eXlGRTxt5LH1oQdAFCPJY9FEb569c/bm6D3/L3r3/d3Aa//RaDP2FI8xj8AeNZiUFgNGIAYgBiADkYg9vEamPx0G6dE+2zDqtP2aqzVYoR9WMwPXW27h/t/8j92UC3RfyK+RTTZkTXj8FWzWnLufmIAXdHY/Bx6vRPu7r/gzE4MZ+sJYfRLWNwW/PRefUEWu1Z9C+e0ik1a9m6X/S/LZLD6E78UrR6ms76dPp3iuzWX570nXjUozCcx/826PR5RQyOjjtLoxjw6bl/Ivdj0M/As+I3e64Y8Onx6waPtG/Vb4679WhnPjLAJ1eRQQxADCBiABEDiBhAxAAiBhAxgIgBZCMGPnHAWOp3A0lgCLvvBmLAz7e1++zjUTFgCGIAO78URRIYgX8wBTEAMYCIAUQMIGIAEQOI7zeAvMN/7L471vK0LrrVfRjU9WOwVXPacm4+YsCd7zcA328Avt8A4vsNIL7fAOL7DSCuIkPEACIGEDGAiAFEDCBiALHfAPIOH7TeHWt5Whfd6j4M6vox2Ko5bTk3HzHgzn4DsN8A7DeA2G8Asd8AYr8BxFVkiBhAxAAiBhAxgIgBRAwg9htA3uGD1rtjLU/rolvdh0FdPwZbNact5+YjBtzZbwD2G4D9BhD7DSD2G0DsN4C4igwRA4gYQMQAIgYQMYCIAcR+A8g7fNB6d6zlaV10q/swqOvHYKvmtOXcfMSAO/sNwH4DsN8AYr8BxH4DiP0GEFeRIWIAEQOIGEDEACIGEDGA2G8AeYcPWu+OtTyti251HwZ1/Rhs1Zy2nJuPGHBnvwHYbwD2G0DsN4DYbwCx3wDiKjJEDCBiABEDiBhAxAAiBpDeZ4q+e46vNchh9o24GqvvBstLUd84wy/wBcd4tTUs5jPCKz4nBnn9MV5tDa82n+/Xj8H0l4fZOnY+vNBp37La//a7Zf/l/br+1v0H698W6uNqltpt7wzamU/deXURjh7X9ytiUBz59KGt5Th6v6NZ5+gQh47lkfqdY+kUeXCd6+GaB3ti3OvafTeYuv0vi1NnatZ/q05/kqv1my9zZ6xi8rvH1a9fNJ4uUtRprs/uQEfrF+t2XSdi0GnsdGiu0YMv86EzrPnE0/WfXqSo01yf3YGO1u8cy+U8NwavWLJzdW4Tdf2tUq+o/5XrUNRfnc/qQM8d97rq6wbTnsULf/QpRalV086rL+FWqc4Qs5ks7xdFzh3CsvFokU6den1263TWue7WP67v94OvIr/6ZXinl5naz4vBq38Uvd+POnb9vBjAYWIAYgBiAMl/Hep+EfWofHkAAAAASUVORK5CYII=" alt="" />

②若格式说明符是c%则对所有输入内容都认为是合法并给变量赋值。

③若格式说明符是s%,则从第一个非空白字符开始认为合法字符直到遇到空白字符。

VC6.0反汇编结果(可以看出scanf函数取参数表中取地址的顺序与printf相同,都是倒着。)

 :    #include<stdio.h>
: int main (void)
: {
push ebp
mov ebp,esp
sub esp,50h
push ebx
push esi
push edi
lea edi,[ebp-50h]
0040101C mov ecx,14h
mov eax,0CCCCCCCCh
rep stos dword ptr [edi]
: int i=;
mov dword ptr [ebp-],
: char a,b,c;
: printf("%c\n",a);
0040102F movsx eax,byte ptr [ebp-]
push eax
push offset string "%c\n" (00425fa4)
call printf ()
0040103E add esp,
: while(i<)
cmp dword ptr [ebp-],
jge main+77h ()
: {scanf("%c%c%c",&a,&b,&c);
lea ecx,[ebp-10h];取变量c的偏移地址
0040104A push ecx
0040104B lea edx,[ebp-0Ch];取变量b的偏移地址
0040104E push edx
0040104F lea eax,[ebp-] ;取变量a的偏移地址
push eax
push offset string "%c" (0042501c)
call scanf (004010a0)
0040105D add esp,10h
: printf("%c%c%c\n",a,b,c);
movsx ecx,byte ptr [ebp-10h]
push ecx
movsx edx,byte ptr [ebp-0Ch]
push edx
0040106A movsx eax,byte ptr [ebp-]
0040106E push eax
0040106F push offset string "%c%c%c\n" ()
call printf ()
add esp,10h
: i++;
0040107C mov ecx,dword ptr [ebp-]
0040107F add ecx,
mov dword ptr [ebp-],ecx
: }
jmp main+31h ()
: return ;
xor eax,eax
: }
pop edi
0040108A pop esi
0040108B pop ebx
0040108C add esp,50h
0040108F cmp ebp,esp
call __chkesp ()
mov esp,ebp
pop ebp
ret

以上。

【C】貌似不友好的scanf()的更多相关文章

  1. ASP.NET Core 2.1 : 十四.静态文件与访问授权、防盗链

    我的网站的图片不想被公开浏览.下载.盗链怎么办?本文主要通过解读一下ASP.NET Core对于静态文件的处理方式的相关源码,来看一下为什么是wwwroot文件夹,如何修改或新增一个静态文件夹,为什么 ...

  2. <转>程序员的心理疾病

    注:本文转自大神王垠的博客 原文出处 http://www.yinwang.org/blog-cn/2014/02/09/programmer-mental/ 说实话,虽然似乎为之奋斗了十多年,在真正 ...

  3. poj1477(水)

    犯了一个错误,贡献了一次CE: G++里面没有头文件,用scanf会CE:然而C++就可以. 两大cow解释: 最好不要c 的输入和c++的一起用 (特别是关同步的时候) 然而好像他们也不是很了解.. ...

  4. ## ucore Lab0 一些杂记

    ucore Lab0 一些杂记 前一阵子开始做 MIT 6.828,做了两三个实验才发现清华的 ucore 貌似更友好一些,再加上前几个实验也与6.828 有所重叠,于是决定迁移阵地. 文章计划分两类 ...

  5. uva 6757 Cup of Cowards(中途相遇法,貌似)

    uva 6757 Cup of CowardsCup of Cowards (CoC) is a role playing game that has 5 different characters (M ...

  6. scanf和cin的差异

    scanf和cin的差异 引例:http://www.cnblogs.com/shenben/p/5516996.html 大家都知道,在C++中有两种输入.输出方式—scanf和cin,但是,它们之 ...

  7. 站点维护使用app_offline.htm页面提供友好的更新提示

    进行站点维护时为了以一个友好的方式提示给用户,比如什么“本网站正在更新”等等的信息可以建立一个叫app_offline.htm 的静态HTM页面文件,其中修改成你要临时显示的内容,将其放在你的应用的根 ...

  8. [WC 2005]友好的生物

    Description $W$ 星球是一个和地球一样气候适宜.物种聚集的星球.经过多年的研究,外星生物学家们已经发现了数万种生物,而且这个数字还在不断增大. $W$ 星球上的生物很有趣,有些生物之间很 ...

  9. ALGO-117_蓝桥杯_算法训练_友好数

    问题描述 有两个整数,如果每个整数的约数和(除了它本身以外)等于对方,我们就称这对数是友好的.例如: 9的约数和有:+= 4的约数和有:+= 所以9和4不是友好的. 220的约数和有: = 284的约 ...

随机推荐

  1. 【java】google的zxing架包生成二维码和读取二维码【可带文字和logo】

    承接RC4生成不重复字符串的需求之后,因为优惠码要方便用户使用的缘故,所以思来想去,觉得还是直接生成二维码给用户直接扫比较实用,也不用用户专门记录冗长的优惠码编号. ================= ...

  2. Odoo POS

    Jeffery Q:913547235     Odoo 8 只支持 ean13条码 Barcode scanner相当于键盘,30ms 条码枪输出类型,QWERTY     pos配置       ...

  3. C++11 并发指南三(std::mutex 详解)(转)

    转自:http://www.cnblogs.com/haippy/p/3237213.html 上一篇<C++11 并发指南二(std::thread 详解)>中主要讲到了 std::th ...

  4. sonar + ieda实现提交代码前代码校验

    代码风格不同一直是一件停头疼的事情,因为不同的工作经验,工作经历,每个人的代码风格不尽相同,造成一些代码在后期的维护当中难以维护, 查阅一些资料之后发现 idea + sonar 的方式比较适合我,实 ...

  5. [转]si设置

    好吧,我有代码格式的强迫症,代码不整齐,我看的都头疼,之前一直喜欢用SourceStyler C++的,但是这个在win7下貌似不能使用,只能转向astyle了. http://www.cnblogs ...

  6. Autofac基本使用(转载)

    AutoFac是.net平台下的IOC容器产品,它可以管理类之间的复杂的依赖关系.在使用方面主要是register和resolve两类操作. 这篇文章用单元测试的形式列举了AutoFac的常用使用方法 ...

  7. HDU 5296 Annoying problem LCA+树状数组

    题解链接 Annoying problem Time Limit: 16000/8000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/O ...

  8. 使用Entity Framework和WCF Ria Services开发SilverLight之6:查找指定字段

    对数据库表指定字段的查找,又是实际工作中的一项必要工作.SL客户端仅获取实际需要的指定的字段,好处很多,比如:有助于减少网络流量. 有两类这样的使用场景. 1:联表查询不需要外键表 在上一篇中,我们使 ...

  9. GCJ Qualification Round 2016 C题

    题意是给定了一个叫“jamcoin”的定义,让你生成足够数量满足条件的jamcoin. jamcoin其实就可以理解成一个二进制整数,题目要求的要么长度为16位,要么为32位,一头一尾两个位必须是1, ...

  10. EasyDarwin开源流媒体社区视频教程

    EasyDarwin开源社区出视频教程了,经过几个深夜的努力,终于将第一次课程的5个课时的视频教程录好<EasyDarwin开源流媒体服务器:编译.配置.部署>,EasyDarwin后面会 ...