不要用scanf函数!!!!


原文转自:http://bbs.itheima.com/thread-138989-1-1.html


大家学习C语言的时候,一定也有很多人告诉你不要使用scanf,那么究竟是为什么呢
scanf这个函数确实有很多问题:
1、通常,我们不在会scanf格式串中加入显式的空白,这是因为在scanf格式串中空白字符如\n并不表示换行符,而是读取并放弃连续的空白字符,而且像%d这样的格式也会舍弃前面的空白。
如果你使用%d\n这样的代码会让scanf读到非空白字符为止,而这可能需要读到下一行才能找到,这时你可以去掉\n而仅仅使用%d,但你的程序可能需要跳过那个没有读入的换行符。
设计scanf函数是用来读取自由格式的输入的,格式%d%d%d既可以读入:

  1. 1 2 3
复制代码

又可以读入:
  1. 1
  2. 2
  3. 3
复制代码

如果一定要用,可以使用:
  1. scanf("%d%*[\n]",&n);
复制代码

但即使这样也不能解决scanf所有的问题。
2、scanf函数对换行符的处理几乎可以说一定会带来问题,例如混用scanf和gets函数或其他任何输入例程的调用。
例如我们有这样一段代码:
  1. int i;
  2. char s[100];
  3. printf("请输入一个数字:");
  4. scanf("%d",&i);
  5. printf("请输入一个字符串:");
  6. gets(s);
  7. printf("您输入的是 %d 和 \"%s\"\n",i,s);
复制代码

如果这样输入:
  1. 20
  2. hello there
复制代码

这时scanf会读取20,但不会读到后面的换行符,于是换行符被gets函数读取,这就导致gets读入了空行,而"hello there"这个字符串根本没有读到。
而如果这样输入:
  1. 20 hello there
复制代码

这时代码就会符合设计初衷。
3、在scanf转换数字的时候,任何非数字的字符都会终止转换,被保留在输入流中。而这样就导致一个问题,在不使用其他手段处理时,当用户不可预料的输入非数字的字符,scanf就会被不断的阻碍,因为sanf无法跳过这些不合法的字符。
例如你希望利用返回值确保用户的输入合法时,你可能会写这样一段代码:
  1. int num;
  2. while(1)
  3. {
  4.         printf("请输入一个数字:");
  5.         if(scanf("%d",&num) == 1) break;
  6.         printf("输入不合法,请再试一次:");
  7. }
复制代码



乍看之下似乎没什么问题,但事实上,如果你意外的输入了非数字的字符,例如字母x,那么这个程序就会陷入无限的循环中,不断的提示输入不合法,却并没有重新输入的机会。4、scanf函数的%s格式还有着和gets函数有一样的问题,即不可知输入缓冲区的大小,如果输入行太长,就无法避免缓冲区溢出。
5、scanf的名称来自scan formatted,很明显它的设计应该更适用于相对整齐和结构化的输入,但在交互中用户的输入是缺乏格式化的,你要考虑的可能情况不仅仅是输入不合法的字符,还可能是太长、太短甚至干脆未输入、提前EOF等,而对scanf来说这些都是很麻烦的。


  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值