C语言中scanf函数的原样输入的坑及解决

 更新时间:2022年07月13日 11:03:03   作者:嵌入式软件工程师  
这篇文章主要介绍了C语言中scanf函数的原样输入的坑及解决方案,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

scanf函数的原样输入的坑及解决

scanf函数是C语言里一个输入函数,但其有很多地方需要注意:

1、scanf函数格式控制后面输入

的应该是变量的地址而不是变量本身(即变量名)

例,输入a,b 两个整型变量的值的时候,很多初学者会写成

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

这样写是错的,应该写成

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

2、scanf函数的输入是有顺序的

例如:

scanf(“%d %d”,&a,&b)

第一个%d是属于a的,第二个%d是属于b的

3、最重要的一点就是scanf切记要原样输入

即:

scanf(“a = %d,b = %d”,&a,&b);

输入的是时候应该写成“a = 1,b = 2”,记住逗号都要原样输入。

若是这样的话;

scanf(“a = %d b = %d”,&a,&b);

这样的话就要写成“a = 1 b =2”就连空格都要原样输入

总之一句话,除了占位符%d,%f,%lf等之类外的其他所有东西都要原样输入,包括空格,逗号

4、还有一个

如果scanf("%d %d %d",&a,&b,&c);,那么这时候可以在输入界面输入一个再按回车再输入下一个这样也是可以的,也可以按照这个格式在一行中进行原样输入。

总之中间有空格的就用空格隔开,如果是逗号的就用逗号来隔开,如果什么都没,即连在一块的话就按照输入格式输入即可。

scanf输入多个数据出现的问题

问题引出

如果使用scanf函数一次输入多个数据,只能是整型和浮点型,如果有char字符型混合输入,就会出现问题:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8OJapclT-1607332110976)(Pasted%20Graphic.png)]

图中可以看到:num3的值并没有打印出来,出现这种情况的原因是什么呢???

执行原理

让我们先大概的过一下里面的执行原理:

  • 在执行scanf函数的时候,会让用户输入一个数据,数据输入完毕之后,并不是将这个数据直接赋值给变量,而是先将数据存储在缓冲区,输入的任何数据都会存储在缓冲区中
  • 在执行scanf函数的时候,会先检查缓冲区中是否有数据,如果缓冲区中没有数据,那么就会让用户从键盘输入,如果缓冲区中有数据,直接从缓冲区中将数据拿出来,不会让用户输入数据
  • 当从缓冲区中拿数据的时候,如果要拿的数据的类型是整型或者实型,如果拿到的数据的类型是空格、回车、Tab键,就会被自动忽略,继续往下拿;如果要拿的数据是字符型,不会忽略任何数据

程序分析

我们来分析下面的一段程序:程序中要求用户输入一个整型数据num1,但是这个时候我们偏偏输入两个整型数据10、20,这个时候缓冲区其实有四个数据:10、空格、20、换行,执行第一个printf后结果为10,这是我们事先预料好的;当第二个scanf执行的时候,程序根本就不会让用户输入数据,因为缓冲区中已经有整型数据20了【当从缓冲区中拿数据的时候,如果要拿的数据的类型是整型或者实型,如果拿到的数据的类型是空格、回车、Tab键,就会被自动忽略,继续往下拿】,所以最终程序会直接打印出num2=20

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-uSu3YfSK-1607332110978)(Pasted%20Graphic%201.png)]

让我们再回头看第一个程序:为什么num3的值打印出来的结果为空???

执行完第11行程序以后,缓冲区中的数据为10、空格、2.5、空格、a、换行;打印num1、num2的值的时候,因为是整型或者浮点型,程序会自动忽略空格和换行,所以输出结果为num1=10,num2=2.500000;但是num3是一个字符型的数据,程序并不会忽略任何的数据,最后打印出来的结果为num3= ;【这里打印出来了一个空格,并不是空】

解决方案

那这个时候就有问题了,如果scanf输入多个数据中包含字符型数据时,我就是想要输出来字符型数据,该怎么做呢???

解决方案:通过rewind(stdin);这行代码把缓冲区中的数据全部清空,这个时候缓冲区中没有任何数据了

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9UNqDCfl-1607332110979)(Pasted%20Graphic%202.png)]

写C代码时,如果遇到整型、浮点型、字符型同时出现在scanf函数中的时候,要十分注意缓冲区中数据的情况!!

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • QT定时器事件的实现示例

    QT定时器事件的实现示例

    本文介绍了QT定时器事件的概念和原理,阐述了其工作方式及实现方法,QT定时器事件可以用于在一定时间间隔内执行特定的任务,从而实现定时操作和控制,具有一定的参考价值,感兴趣的可以了解一下
    2023-08-08
  • C与C++ 无参函数的区别解析

    C与C++ 无参函数的区别解析

    在《C++ 编程思想》:“关于无参函数声明,C与C++有很大的差别。在C语言中,声明int fun1(),意味着一个可以有任意数目和类型的函数;而在C++中,指的却是一个没有参数的函数”
    2013-07-07
  • C语言宏定义使用分析

    C语言宏定义使用分析

    在宏定义中,“宏名称”和“宏字符串”是通过“空格”来区分的,某些朋友不要混淆了,接下来请祥看本文
    2012-12-12
  • C++深入探究不同的继承体系

    C++深入探究不同的继承体系

    继承是C++面向对象编程中的一门。继承是子类继承父类的特征和行为,或者是继承父类得方法,使的子类具有父类得的特性和行为。重写是子类对父类的允许访问的方法实行的过程进行重新编写,返回值和形参都不能改变。就是对原本的父类进行重新编写,但是外部接口不能被重写
    2022-05-05
  • Dijkstra算法与Prim算法的异同案例详解

    Dijkstra算法与Prim算法的异同案例详解

    这篇文章主要介绍了Dijkstra算法与Prim算法的异同案例详解,本篇文章通过简要的案例,讲解了该项技术的了解与使用,以下就是详细内容,需要的朋友可以参考下
    2021-09-09
  • C语言三个函数的模拟实现详解

    C语言三个函数的模拟实现详解

    这篇文章主要为大家详细介绍了C语言三个函数的模拟实现,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望能够给你带来帮助
    2022-03-03
  • C语言单链表实现多项式相加

    C语言单链表实现多项式相加

    这篇文章主要为大家详细介绍了C语言单链表实现多项式相加,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-10-10
  • C++ 构造双向链表的实现代码

    C++ 构造双向链表的实现代码

    本篇文章是对C++中构造双向链表的实现代码进行了详细的分析介绍,需要的朋友参考下
    2013-05-05
  • C++11非受限联合体的使用

    C++11非受限联合体的使用

    本文主要介绍了C++11非受限联合体的使用,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-01-01
  • 浅谈C语言函数调用参数压栈的相关问题

    浅谈C语言函数调用参数压栈的相关问题

    下面小编就为大家带来一篇浅谈C语言函数调用参数压栈的相关问题。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2016-09-09

最新评论