精华内容
下载资源
问答
  • 通过scanf函数从键盘输入数据
    2020-12-23 03:20:22

    通过

    scanf

    函数从键盘输入数据

    1

    )当调用

    scanf

    函数从键盘输入数据时,最后一定要按下回车键,

    scanf

    函数才能接受键盘

    输入的数据。

    2

    )输入数据值

    当键盘输入数据时,输入的数值数据之间用间隔符隔开。列

    <

    间隔符

    >10<

    间隔符

    >20

    <

    间隔符

    >

    此处间隔符可以是空格符、制表符(

    Tab

    )

    、回车符。

    3

    )跳过输入数据的方法

    可以在格式字符和

    %

    之间加上一个

    *

    ,它的作用是跳过对应的输入数据。列

    Int

    a1,a2, a3;

    Scanf("%d%d*%d%d%d",&a1,&a2,&a3);

    当输入如下数据时:

    10

    20

    30

    40

    将把

    10

    赋给

    a1

    ,跳过

    20

    ,把

    30

    赋给

    a2

    ,把

    10

    赋给

    a3

    4

    )在格式字符串中插入其他字符

    如果想在屏幕上输入字符串来提示,应该使用

    printf

    函数,如果在

    scanf

    的格式控制字符串

    中插入其他字符,则在输入时要求按一对一的位置原样输入这些字符

    1

    Int a1,a2,a3;

    Scanf

    (

    inpat a1,a2,a3:%d%d%d

    ,&a1,&a2,&a3

    )

    ;

    要求按以下形式进行输入

    Input a1,a2,a3:102030

    1

    以下程序由终端出入两个整数给变量

    x

    y

    ,在交换

    x

    y

    的值后,在输出

    x

    y

    ,验证两

    个变量中的数是否正确的进行了交换。

    #inclube

    "stdio.h"

    Main()

    {int x,y,t;

    Printf("enter x&y:\n");

    Scanf("%d %d",&x,&y);

    Printf9("x=%d y=%d\n",x,y);

    T=x;x=y;y=t;

    Printf("x=%d y=%d\n",x,y);

    }

    2

    输入一个

    doulbe

    类型的数,使该数保留小数点后两位,对第三位小数进行四舍五入后处理,

    然后输出此数,以便验证处理是否正确。

    更多相关内容
  • 使用scanf从键盘输入数据

    千次阅读 2021-11-25 11:42:02
    程序是人机交互的媒介,有输出必然也有输入,第三章我们讲解了如何将数据输出到显示器上,本章我们开始讲解如何从键盘输入数据。在C语言中,有多个函数可以键盘获得用户输入: scanf():和 printf() 类似,scanf...

    程序是人机交互的媒介,有输出必然也有输入,第三章我们讲解了如何将数据输出到显示器上,本章我们开始讲解如何从键盘输入数据。在C语言中,有多个函数可以从键盘获得用户输入:

    • scanf():和 printf() 类似,scanf() 可以输入多种类型的数据。
    • getchar()、getche()、getch():这三个函数都用于输入单个字符。
    • gets():获取一行数据,并作为字符串处理。


    scanf() 是最灵活、最复杂、最常用的输入函数,但它不能完全取代其他函数,大家都要有所了解。

    本节我们只讲解 scanf(),其它的输入函数将在下节讲解。

    scanf()函数

    scanf 是 scan format 的缩写,意思是格式化扫描,也就是从键盘获得用户输入,和 printf 的功能正好相反。

    我们先来看一个例子:

     
    
    1. #include <stdio.h>
    2. int main()
    3. {
    4. int a = 0, b = 0, c = 0, d = 0;
    5. scanf("%d", &a); //输入整数并赋值给变量a
    6. scanf("%d", &b); //输入整数并赋值给变量b
    7. printf("a+b=%d\n", a+b); //计算a+b的值并输出
    8. scanf("%d %d", &c, &d); //输入两个整数并分别赋值给c、d
    9. printf("c*d=%d\n", c*d); //计算c*d的值并输出
    10. return 0;
    11. }

    运行结果:
    12↙
    60↙
    a+b=72
    10 23↙
    c*d=230

    表示按下回车键。

    从键盘输入12,按下回车键,scanf() 就会读取输入数据并赋值给变量 a;本次输入结束,接着执行下一个 scanf() 函数,再从键盘输入 60,按下回车键,就会将 60 赋值给变量 b,都是同样的道理。

    第 8 行代码中,scanf() 有两个以空格分隔的%d,后面还跟着两个变量,这要求我们一次性输入两个整数,并分别赋值给 c 和 d。注意"%d %d"之间是有空格的,所以输入数据时也要有空格。对于 scanf(),输入数据的格式要和控制字符串的格式保持一致。

    其实 scanf 和 printf 非常相似,只是功能相反罢了:

     
    
    1. scanf("%d %d", &a, &b); // 获取用户输入的两个整数,分别赋值给变量 a 和 b
    2. printf("%d %d", a, b); // 将变量 a 和 b 的值在显示器上输出

    它们都有格式控制字符串,都有变量列表。不同的是,scanf 的变量前要带一个&符号。&称为取地址符,也就是获取变量在内存中的地址。

    在《数据在内存中的存储》一节中讲到,数据是以二进制的形式保存在内存中的,字节(Byte)是最小的可操作单位。为了便于管理,我们给每个字节分配了一个编号,使用该字节时,只要知道编号就可以,就像每个学生都有学号,老师会随机抽取学号来让学生回答问题。字节的编号是有顺序的,从 0 开始,接下来是 1、2、3……

    下图是 4G 内存中每个字节的编号(以十六进制表示):



    这个编号,就叫做地址(Address)。int a;会在内存中分配四个字节的空间,我们将第一个字节的地址称为变量 a 的地址,也就是&a的值。对于前面讲到的整数、浮点数、字符,都要使用 & 获取它们的地址,scanf 会根据地址把读取到的数据写入内存。

    我们不妨将变量的地址输出看一下:

     
    
    1. #include <stdio.h>
    2. int main()
    3. {
    4. int a='F';
    5. int b=12;
    6. int c=452;
    7. printf("&a=%p, &b=%p, &c=%p\n", &a, &b, &c);
    8. return 0;
    9. }

    输出结果:
    &a=0x18ff48, &b=0x18ff44, &c=0x18ff40

    %p是一个新的格式控制符,它表示以十六进制的形式(带小写的前缀)输出数据的地址。如果写作%P,那么十六进制的前缀也将变成大写形式。
     


    图:a、b、c 的内存地址

    注意:这里看到的地址都是假的,是虚拟地址,并不等于数据在物理内存中的地址。虚拟地址是现代计算机因内存管理的需要才提出的概念,我们将在《 C语言和内存》专题中详细讲解。

    再来看一个 scanf 的例子:

     
    
    1. #include <stdio.h>
    2. int main()
    3. {
    4. int a, b, c;
    5. scanf("%d %d", &a, &b);
    6. printf("a+b=%d\n", a+b);
    7. scanf("%d %d", &a, &b);
    8. printf("a+b=%d\n", a+b);
    9. scanf("%d, %d, %d", &a, &b, &c);
    10. printf("a+b+c=%d\n", a+b+c);
    11. scanf("%d is bigger than %d", &a, &b);
    12. printf("a-b=%d\n", a-b);
    13. return 0;
    14. }

    运行结果:

    10    20↙
    a+b=30
    100 200↙
    a+b=300
    56,45,78↙
    a+b+c=179
    25 is bigger than 11↙
    a-b=14


    第一个 scanf() 的格式控制字符串为"%d %d",中间有一个空格,而我们却输入了10    20,中间有多个空格。第二个 scanf() 的格式控制字符串为"%d   %d",中间有多个空格,而我们却输入了100 200,中间只有一个空格。这说明 scanf() 对输入数据之间的空格的处理比较宽松,并不要求空格数严格对应,多几个少几个无所谓,只要有空格就行。

    第三个 scanf() 的控制字符串为"%d, %d, %d",中间以逗号分隔,所以输入的整数也要以逗号分隔。

    第四个 scanf() 要求整数之间以is bigger than分隔。

    用户每次按下回车键,程序就会认为完成了一次输入操作,scanf() 开始读取用户输入的内容,并根据格式控制字符串从中提取有效数据,只要用户输入的内容和格式控制字符串匹配,就能够正确提取。

    本质上讲,用户输入的内容都是字符串,scanf() 完成的是从字符串中提取有效数据的过程。

    连续输入

    在本节第一段示例代码中,我们一个一个地输入变量 a、b、c、d 的值,每输入一个值就按一次回车键。现在我们改变输入方式,将四个变量的值一次性输入,如下所示:

    12 60 10 23↙
    a+b=72
    c*d=230

    可以发现,两个 scanf() 都能正确读取。合情合理的猜测是,第一个 scanf() 读取完毕后没有抛弃多余的值,而是将它们保存在了某个地方,下次接着使用。

    如果我们多输入一个整数,会怎样呢?

    12 60 10 23 99↙
    a+b=72
    c*d=230

    这次我们多输入了一个 99,发现 scanf() 仍然能够正确读取,只是 99 没用罢了。

    如果我们少输入一个整数,又会怎样呢?

    12 60 10↙
    a+b=72
    23↙
    c*d=230

    输入三个整数后,前两个 scanf() 把前两个整数给读取了,剩下一个整数 10,而第三个 scanf() 要求输入两个整数,一个单独的 10 并不能满足要求,所以我们还得继续输入,凑够两个整数以后,第三个 scanf() 才能读取完毕。

    从本质上讲,我们从键盘输入的数据并没有直接交给 scanf(),而是放入了缓冲区中,直到我们按下回车键,scanf() 才到缓冲区中读取数据。如果缓冲区中的数据符合 scanf() 的要求,那么就读取结束;如果不符合要求,那么就继续等待用户输入,或者干脆读取失败。我们将在本章的《C语言缓冲区(缓存)详解》《结合C语言缓冲区谈scanf()函数》两节中详细讲解缓冲区。

    注意,如果缓冲区中的数据不符合 scanf() 的要求,要么继续等待用户输入,要么就干脆读取失败,上面我们演示了“继续等待用户输入”的情形,下面我们对代码稍作修改,演示“读取失败”的情形。

     
    
    1. #include <stdio.h>
    2. int main()
    3. {
    4. int a = 1, b = 2, c = 3, d = 4; //修改处:给变量赋予不同的初始值
    5. scanf("%d", &a);
    6. scanf("%d", &b);
    7. printf("a=%d, b=%d\n", a, b);
    8. scanf("%d %d", &c, &d);
    9. printf("c=%d, d=%d\n", c, d);
    10. return 0;
    11. }

    运行结果:

    12 60 a10↙
    a=12, b=60
    c=3, d=4

    前两个整数被正确读取后,剩下了 a10,而第三个 scanf() 要求输入两个十进制的整数,a10 无论如何也不符合要求,所以只能读取失败。输出结果也证明了这一点,c 和 d 的值并没有被改变。

    这说明 scanf() 不会跳过不符合要求的数据,遇到不符合要求的数据会读取失败,而不是再继续等待用户输入。

    总而言之,正是由于缓冲区的存在,才使得我们能够多输入一些数据,或者一次性输入所有数据,这可以认为是缓冲区的一点优势。然而,缓冲区也带来了一定的负面影响,甚至会导致很奇怪的行为,请看下面的代码:

     
    
    1. #include <stdio.h>
    2. int main()
    3. {
    4. int a = 1, b = 2;
    5. scanf("a=%d", &a);
    6. scanf("b=%d", &b);
    7. printf("a=%d, b=%d\n", a, b);
    8. return 0;
    9. }

    输入示例:

    a=99↙
    a=99, b=2

    输入a=99,按下回车键,程序竟然运行结束了,只有第一个 scanf() 成功读取了数据,第二个 scanf() 仿佛没有执行一样,根本没有给用户任何机会去输入数据。

    如果我们换一种输入方式呢?

    a=99b=200↙
    a=99, b=200

    这样 a 和 b 都能够正确读取了。注意,a=99b=200中间是没有任何空格的。

    肯定有好奇的小伙伴又问了,如果a=99b=200两个数据之间有空格又会怎么样呢?我们不妨亲试一下:

    a=99 b=200↙
    a=99, b=2

    你看,第二个 scanf() 又读取失败了!在前面的例子中,输入的两份数据之前都是有空格的呀,为什么这里不能带空格呢,真是匪夷所思。好吧,这个其实还是跟缓冲区有关系,我将在《结合C语言缓冲区谈scanf()函数》中深入讲解。

    要想破解 scanf() 输入的问题,一定要学习缓冲区,它能使你对输入输出的认识上升到一个更高的层次,以后不管遇到什么疑难杂症,都能迎刃而解。可以说,输入输出的“命门”就在于缓冲区。

    输入其它数据

    除了输入整数,scanf() 还可以输入单个字符、字符串、小数等,请看下面的演示:

     
    
    1. #include <stdio.h>
    2. int main()
    3. {
    4. char letter;
    5. int age;
    6. char url[30];
    7. float price;
    8. scanf("%c", &letter);
    9. scanf("%d", &age);
    10. scanf("%s", url); //可以加&也可以不加&
    11. scanf("%f", &price);
    12. printf("26个英文字母的最后一个是 %c。\n", letter);
    13. printf("C语言中文网已经成立%d年了,网址是 %s,开通VIP会员的价格是%g。\n", age, url, price);
    14. return 0;
    15. }

    运行示例:

    z↙
    6↙
    http://c.biancheng.net↙
    159.9↙
    26个英文字母的最后一个是 z。
    C语言中文网已经成立6年了,网址是 http://c.biancheng.net,开通VIP会员的价格是159.9。

    scanf() 和 printf() 虽然功能相反,但是格式控制符是一样的,单个字符、整数、小数、字符串对应的格式控制符分别是 %c、%d、%f、%s。

    对读取字符串的说明

    在《C语言处理英文字符》一节中,我们谈到了字符串的两种定义形式,它们分别是:

    char str1[] = "http://c.biancheng.net";
    char *str2 = "C语言中文网";

    这两种形式其实是有区别的,第一种形式的字符串所在的内存既有读取权限又有写入权限,第二种形式的字符串所在的内存只有读取权限,没有写入权限。printf()、puts() 等字符串输出函数只要求字符串有读取权限,而 scanf()、gets() 等字符串输入函数要求字符串有写入权限,所以,第一种形式的字符串既可以用于输出函数又可以用于输入函数,而第二种形式的字符串只能用于输出函数。

    另外,对于第一种形式的字符串,在[ ]里面要指明字符串的最大长度,如果不指明,也可以根据=后面的字符串来自动推算,此处,就是根据"http://c.biancheng.net"的长度来推算的。但是在前一个例子中,开始我们只是定义了一个字符串,并没有立即给它赋值,所以没法自动推算,只能手动指明最大长度,这也就是为什么一定要写作char url[30],而不能写作char url[]的原因。

    读者还要注意第 11 行代码,这行代码用来输入字符串。上面我们说过,scanf() 读取数据时需要的是数据的地址,整数、小数、单个字符都要加&取地址符,这很容易理解;但是对于此处的 url 字符串,我们并没有加 &,这是因为,字符串的名字会自动转换为字符串的地址,所以不用再多此一举加 & 了。当然,你也可以加上,这样虽然不会导致错误,但是编译器会产生警告,至于为什么,我们将会在《数组和指针绝不等价,数组是另外一种类型》《数组在什么时候会转换为指针》中讲解。

    关于字符串,后续章节我们还会专门讲解,这里只要求大家会模仿,不要彻底理解,也没法彻底理解。

    最后需要注意的一点是,scanf() 读取字符串时以空格为分隔,遇到空格就认为当前字符串结束了,所以无法读取含有空格的字符串,请看下面的例子:

     
    
    1. #include <stdio.h>
    2. int main()
    3. {
    4. char author[30], lang[30], url[30];
    5. scanf("%s %s", author, lang);
    6. printf("author:%s \nlang: %s\n", author, lang);
    7. scanf("%s", url);
    8. printf("url: %s\n", url);
    9. return 0;
    10. }

    运行示例:

    YanChangSheng C-Language↙
    author:YanChangSheng
    lang: C-Language
    http://c.biancheng.net http://biancheng.net↙
    url: http://c.biancheng.net

    对于第一个 scanf(),它将空格前边的字符串赋值给 author,将空格后边的字符串赋值给 lang;很显然,第一个字符串遇到空格就结束了,第二个字符串到了本行的末尾结束了。

    或许第二个 scanf() 更能说明问题,我们输入了两个网址,但是 scanf() 只读取了一个,就是因为这两个网址以空格为分隔,scanf() 遇到空格就认为字符串结束了,不再继续读取了。

    scanf() 格式控制符汇总

    格式控制符说明
    %c读取一个单一的字符
    %hd、%d、%ld读取一个十进制整数,并分别赋值给 short、int、long 类型
    %ho、%o、%lo读取一个八进制整数(可带前缀也可不带),并分别赋值给 short、int、long 类型
    %hx、%x、%lx读取一个十六进制整数(可带前缀也可不带),并分别赋值给 short、int、long 类型
    %hu、%u、%lu读取一个无符号整数,并分别赋值给 unsigned short、unsigned int、unsigned long 类型
    %f、%lf读取一个十进制形式的小数,并分别赋值给 float、double 类型
    %e、%le读取一个指数形式的小数,并分别赋值给 float、double 类型
    %g、%lg既可以读取一个十进制形式的小数,也可以读取一个指数形式的小数,并分别赋值给 float、double 类型
    %s读取一个字符串(以空白符为结束)
    展开全文
  • 用scanf输入字符型数据时输入的格式要注意什么?使用时应注意的问题:要求在程序运行中输入数据输入数据个数和类型必须与格式说明符一一对应。地址参数形式:&amp变量名(除数组或指针变量)格式控制中有...

    用scanf输入字符型数据时,输入的格式要注意什么?

    使用时应注意的问题:要求在程序运行中输入数据,输入的数据个数和类型必须与格式说明符一一对应。地址参数形式:&amp变量名(除数组或指针变量)格式控制中有普通字符时,必须照原样输入。格式控制中无普通字符时,输入的数值型数据和字符串用空白符分隔,字符型数据不必分隔。double型数据输入时,必须用%lf或%le格式实型数输入时域宽不能用m.n形式的附加说明为了减少不必要的输入量,除了逗号、分号、空格符以外,格式控制中尽量不要出现普通字符,也不要使用"\n"、"\t"等转义字符

    5 输入字符串的格式不正确?

    有几种情况:1。格式未按照网页上的要求填写2。使用全角字符,改成半角3。字数过多

    输入字符串的格式不正确怎么处理?

    做个格式检验吧,如果格式不符合要求,就要求重新输入例:要求字符串必须是字母#include

    从键盘输入一个字符串?

    在C语言中输入字符串后然后打印出来的编程方法如下:

    1.首先需要先定义一个存放字符串的数组空间,如给字符串100个数组空间。

    2.接着使用gets()函数来获取键盘输入的字符串。一般格式为gets(定义的字符数组名)。

    3.然后再使用puts()函数来输出之前输入的字符串内容。一般格式puts(定义的字符数组名)。

    4.最终运行程序,即可成功实现输入字符串,然后原样在屏幕中输出字符串。扩展资料:1.gets从标准输入设备读字符串函数,其可以无限读取,不会判断上限,以回车结束读取,所以程序员应该确保buffer的空间足够大,以便在执行读操作时不发生溢出。2.puts()函数用来向标准输出设备(屏幕)输出字符串并换行,具体为:把字符串输出到标准输出设备,将"\0"转换为回车换行。其调用方式为,puts(s);其中s为字符串字符(字符串数组名或字符串指针)。参考资料:

    利用scanf函数输入多个字符串时,scanf函数的格式与字符串输入的格式应如何设置?

    给你一个例子char buff1[128],buff2[128]scanf("%s%s",buff1,buff2)但是这样的缺点是无法获取到包含空白字符的字符串,因此如果包含空格TAB这样的空白字符,建议使用gets函数

    什么叫字符串的格式?

    置选择区段落格式 ,也就是 把你选中的那一段 进行设置,比如说设置 “首行缩进”或“对齐方式”等,具体看“段落格式”的参数 .版本 2

    .支持库 iext2.程序集 启动窗口程序集

    .程序集变量 设置段落格式, 段落格式.子程序 _按钮1_被单击设置段落格式.首行缩进 = 2

    超级编辑框1.置选择区段落格式 (设置段落格式) " 必需选中某一段

    盘数据是否完好来判断BIOS是否被破坏,如果硬盘

    字符串和变量输出是怎样的格式?

    字符变量,也就是char类型的变量,有两种输出模式: 1按照字符输入。即输出本身的字符,如果是"A",那么就输出A。 有两种方法: 1)用printf输出。 %c格式符是用作char变量输出的,如 charc="M" printf("%c",c) 这样就输出M了。 2)用putchar输出。 putchar功能为输出一个字符,所以 charc="M" putchar(c) 同样是输出M。 2输出char变量的ASCII码值。 char变量存储的本质为ASCII码,所以可以通过printf,用%d或%x输出其值。 charc="M" printf("%d,0x%x\n",c,c) 会分别以10进制和16进制输出M的ASCII码值,即 77,0x4d

    展开全文
  • 从键盘输入12,按下回车键,scanf() 就会读取输入数据并赋值给变量 a;本次输入结束,接着执行下一个 scanf() 函数,再从键盘输入 60,按下回车键,就会将 60 赋值给变量 b,都是同样的道理。 第 8 行代码中,scanf

    scanf()函数

    scanf 是 scan format 的缩写,意思是格式化扫描,也就是从键盘获得用户输入,和 printf 的功能正好相反。

    我们先来看一个例子:

    运行结果:
    12↙
    60↙
    a+b=72
    10 23↙
    c*d=230

    表示按下回车键。

    从键盘输入12,按下回车键,scanf() 就会读取输入数据并赋值给变量 a;本次输入结束,接着执行下一个 scanf() 函数,再从键盘输入 60,按下回车键,就会将 60 赋值给变量 b,都是同样的道理。

    第 8 行代码中,scanf() 有两个以空格分隔的%d,后面还跟着两个变量,这要求我们一次性输入两个整数,并分别赋值给 c 和 d。注意"%d %d"之间是有空格的,所以输入数据时也要有空格。对于 scanf(),输入数据的格式要和控制字符串的格式保持一致。

    其实 scanf 和 printf 非常相似,只是功能相反罢了:

     它们都有格式控制字符串,都有变量列表。不同的是,scanf 的变量前要带一个&符号。&称为取地址符,也就是获取变量在内存中的地址。

    在《数据在内存中的存储》一节中讲到,数据是以二进制的形式保存在内存中的,字节(Byte)是最小的可操作单位。为了便于管理,我们给每个字节分配了一个编号,使用该字节时,只要知道编号就可以,就像每个学生都有学号,老师会随机抽取学号来让学生回答问题。字节的编号是有顺序的,从 0 开始,接下来是 1、2、3……

    下图是 4G 内存中每个字节的编号(以十六进制表示):



    这个编号,就叫做地址(Address)。int a;会在内存中分配四个字节的空间,我们将第一个字节的地址称为变量 a 的地址,也就是&a的值。对于前面讲到的整数、浮点数、字符,都要使用 & 获取它们的地址,scanf 会根据地址把读取到的数据写入内存。

    我们不妨将变量的地址输出看一下:

     输出结果:
    &a=0x18ff48, &b=0x18ff44, &c=0x18ff40

    %p是一个新的格式控制符,它表示以十六进制的形式(带小写的前缀)输出数据的地址。如果写作%P,那么十六进制的前缀也将变成大写形式。
     


    图:a、b、c 的内存地址

    注意:这里看到的地址都是假的,是虚拟地址,并不等于数据在物理内存中的地址。虚拟地址是现代计算机因内存管理的需要才提出的概念,我们将在《 C语言内存精讲》专题中详细讲解。

    再来看一个 scanf 的例子:

     运行结果:

    第一个 scanf() 的格式控制字符串为"%d %d",中间有一个空格,而我们却输入了10    20,中间有多个空格。

    第二个 scanf() 的格式控制字符串为"%d   %d",中间有多个空格,而我们却输入了100 200,中间只有一个空格。这说明 scanf() 对输入数据之间的空格的处理比较宽松,并不要求空格数严格对应,多几个少几个无所谓,只要有空格就行。

    第三个 scanf() 的控制字符串为"%d, %d, %d",中间以逗号分隔,所以输入的整数也要以逗号分隔。

    第四个 scanf() 要求整数之间以is bigger than分隔。

    用户每次按下回车键,程序就会认为完成了一次输入操作,scanf() 开始读取用户输入的内容,并根据格式控制字符串从中提取有效数据,只要用户输入的内容和格式控制字符串匹配,就能够正确提取。

    本质上讲,用户输入的内容都是字符串,scanf() 完成的是从字符串中提取有效数据的过程。

    连续输入

    在本节第一段示例代码中,我们一个一个地输入变量 a、b、c、d 的值,每输入一个值就按一次回车键。

    运行结果:
    12↙
    60↙
    a+b=72
    10 23↙
    c*d=230

    现在我们改变输入方式,将四个变量的值一次性输入,如下所示:

     可以发现,两个 scanf() 都能正确读取。合情合理的猜测是,第一个 scanf() 读取完毕后没有抛弃多余的值,而是将它们保存在了某个地方,下次接着使用。

    如果我们多输入一个整数,会怎样呢?

     这次我们多输入了一个 99,发现 scanf() 仍然能够正确读取,只是 99 没用罢了。

    如果我们少输入一个整数,又会怎样呢?

    输入三个整数后,前两个 scanf() 把前两个整数给读取了,剩下一个整数 10,而第三个 scanf() 要求输入两个整数,一个单独的 10 并不能满足要求,所以我们还得继续输入,凑够两个整数以后,第三个 scanf() 才能读取完毕。

    从本质上讲,我们从键盘输入的数据并没有直接交给 scanf(),而是放入了缓冲区中,直到我们按下回车键,scanf() 才到缓冲区中读取数据。如果缓冲区中的数据符合 scanf() 的要求,那么就读取结束;如果不符合要求,那么就继续等待用户输入,或者干脆读取失败。我们将在本章的

    进入缓冲区(缓存)的世界,破解一切与输入输出有关的疑难杂症》、

    结合C语言缓冲区谈scanf函数》两节中详细讲解缓冲区。

    注意,如果缓冲区中的数据不符合 scanf() 的要求,要么继续等待用户输入,要么就干脆读取失败,上面我们演示了“继续等待用户输入”的情形,下面我们对代码稍作修改,演示“读取失败”的情形。

     运行结果:

    前两个整数被正确读取后,剩下了 a10,而第三个 scanf() 要求输入两个十进制的整数,a10 无论如何也不符合要求,所以只能读取失败。输出结果也证明了这一点,c 和 d 的值并没有被改变。

    这说明 scanf() 不会跳过不符合要求的数据,遇到不符合要求的数据会读取失败,而不是再继续等待用户输入。

    总而言之,正是由于缓冲区的存在,才使得我们能够多输入一些数据,或者一次性输入所有数据,这可以认为是缓冲区的一点优势。然而,缓冲区也带来了一定的负面影响,甚至会导致很奇怪的行为,请看下面的代码:

     输入示例:

    输入a=99,按下回车键,程序竟然运行结束了,只有第一个 scanf() 成功读取了数据,第二个 scanf() 仿佛没有执行一样,根本没有给用户任何机会去输入数据。
    如果我们换一种输入方式呢?

    这样 a 和 b 都能够正确读取了。注意,a=99b=200中间是没有任何空格的。
    肯定有好奇的小伙伴又问了,如果a=99b=200两个数据之间有空格又会怎么样呢?我们不妨亲试一下:

    你看,第二个 scanf() 又读取失败了!在前面的例子中,输入的两份数据之前都是有空格的呀,为什么这里不能带空格呢,真是匪夷所思。好吧,这个其实还是跟缓冲区有关系,我将在

    结合C语言缓冲区谈scanf()函数》中深入讲解。

    要想破解 scanf() 输入的问题,一定要学习缓冲区,它能使你对输入输出的认识上升到一个更高的层次,以后不管遇到什么疑难杂症,都能迎刃而解。可以说,输入输出的“命门”就在于缓冲区。

    输入其它数据

    除了输入整数,scanf() 还可以输入单个字符、字符串、小数等,请看下面的演示:

     运行示例:

     scanf() 和 printf() 虽然功能相反,但是格式控制符是一样的,单个字符、整数、小数、字符串对应的格式控制符分别是 %c、%d、%f、%s。

    对读取字符串的说明

    在《在C语言中使用英文字符》一节中,我们谈到了字符串的两种定义形式,它们分别是:

    这两种形式其实是有区别的,第一种形式的字符串所在的内存既有读取权限又有写入权限,第二种形式的字符串所在的内存只有读取权限,没有写入权限。printf()、puts() 等字符串输出函数只要求字符串有读取权限,而 scanf()、gets() 等字符串输入函数要求字符串有写入权限,所以,第一种形式的字符串既可以用于输出函数又可以用于输入函数,而第二种形式的字符串只能用于输出函数。

    另外,对于第一种形式的字符串,在[ ]里面要指明字符串的最大长度,如果不指明,也可以根据=后面的字符串来自动推算,此处,就是根据"http://c.biancheng.net"的长度来推算的。但是在前一个例子中,开始我们只是定义了一个字符串,并没有立即给它赋值,所以没法自动推算,只能手动指明最大长度,这也就是为什么一定要写作char url[30],而不能写作char url[]的原因。

    读者还要注意第 11 行代码,这行代码用来输入字符串。上面我们说过,scanf() 读取数据时需要的是数据的地址,整数、小数、单个字符都要加&取地址符,这很容易理解;但是对于此处的 url 字符串,我们并没有加 &,这是因为,字符串的名字会自动转换为字符串的地址,所以不用再多此一举加 & 了。当然,你也可以加上,这样虽然不会导致错误,但是编译器会产生警告,至于为什么,我们将会在《数组和指针绝不等价,数组是另外一种类型》《数组到底在什么时候会转换为指针》中讲解。

    关于字符串,后续章节我们还会专门讲解,这里只要求大家会模仿,不要彻底理解,也没法彻底理解。

    最后需要注意的一点是,scanf() 读取字符串时以空格为分隔,遇到空格就认为当前字符串结束了,所以无法读取含有空格的字符串,请看下面的例子:

     运行示例:

     对于第一个 scanf(),它将空格前边的字符串赋值给 author,将空格后边的字符串赋值给 lang;很显然,第一个字符串遇到空格就结束了,第二个字符串到了本行的末尾结束了。

    或许第二个 scanf() 更能说明问题,我们输入了两个网址,但是 scanf() 只读取了一个,就是因为这两个网址以空格为分隔,scanf() 遇到空格就认为字符串结束了,不再继续读取了。

    scanf() 格式控制符汇总

    格式控制符说明
    %c读取一个单一的字符
    %hd、%d、%ld读取一个十进制整数,并分别赋值给 short、int、long 类型
    %ho、%o、%lo读取一个八进制整数(可带前缀也可不带),并分别赋值给 short、int、long 类型
    %hx、%x、%lx读取一个十六进制整数(可带前缀也可不带),并分别赋值给 short、int、long 类型
    %hu、%u、%lu读取一个无符号整数,并分别赋值给 unsigned short、unsigned int、unsigned long 类型
    %f、%lf读取一个十进制形式的小数,并分别赋值给 float、double 类型
    %e、%le读取一个指数形式的小数,并分别赋值给 float、double 类型
    %g、%lg既可以读取一个十进制形式的小数,也可以读取一个指数形式的小数,并分别赋值给 float、double 类型
    %s读取一个字符串(以空白符为结束)
    展开全文
  • 程序是人机交互的媒介,有输出必然也有输入,第三章我们讲解了如何将数据输出到显示器上,本章我们开始讲解如何从键盘输入数据。在C语言中,有多个函数可以键盘获得用户输入: scanf():和 printf() 类似,scanf...
  • #define _CRT_SECURE_NO_WARNINGS #include<stdio.h> int main() { ... //输入数据-使用输入函数scanf scanf("%d%d", &num1, &num2);//取地址符& scanf是c语言提供,scanf_s不是标准c...
  • 功能: 将从键盘输入的字符转化为输入控制符所规定格式的数据,然后存入以输入 参数的值为地址的变量中。 举列演示:&i 表示i的地址,&是一个取地址符 用法二:scanf(“非输入控制符 输入控制符”,...
  • 用scanf函数输入数据,举例并分析错误原因下面的scanf函数输入数据,使a=3,b=7,x=8.5,y=71.82,c1=’A’,c2=’a’。问在键盘上如何输入。程序:#includeint main(){int a, b;float x, y;char c1, c2;scanf("a=%d b...
  • C语言从键盘输入数据

    千次阅读 2021-05-18 17:18:50
    在C语言中,有多个函数可以从键盘获得用户输入scanf():和 printf() 类似,scanf() 可以输入多种类型的数据。getchar()、getche()、getch():这三个函数都用于输入单个字符。gets():获取一行数据,并作为字符串...
  • C语言键盘输入采集scanf函数前面说过C语言的额printf函数,那么这一次说说scanf函数。这两个函数像两兄弟,比如在C++里面经常遇到set和get,就差不到就是scanf和printf的意思,printf用来通过终端输出一些内容,...
  • rust: 从键盘输入数据

    千次阅读 2020-12-29 12:50:58
    下面这个命令,没有C++惯用的构造函数,而是使用了一个函数,返回一个类的实例。 let mut guess = String::new(); rust的编译机制确保这个过程具有极高的运行效率。如果C++这样做,想获得高效率,很繁琐,左值引用...
  • 使用Visual Studio 2019进行C语言编程,有时候需要从键盘读取字符,这时候就要用到scanf()语句。 #include<stdio.h> int main() { char a; scanf("%c", &a); printf("%c \n", a); return 0; } ...
  • 格式化输入函数scanf( )scanf( )功能:按照指定的格式读入键盘输入的若干个任意类型的数据,存入到argument参数所指向的内存单元,函数返回值为读入并赋给argument的数据个数,出错则返回0。scanf( )使用形式:...
  • 1、 使用sanf( )函数,要包含一个头文件<stdio.h> 2、scanf函数是一个阻塞式函数:函数执行...如果我们的一次输入全都是%d类型的,那么无论我们在输入数据时,之间插入 空格、回车、 Tab等其它字符都不影响,都会
  • 本文根本上讲解了scanf函数的应用,以及输入时键盘缓冲区的数据形式,相信读完之后你会对scanf有更深一层次的认识。
  • scanf函数读取缓冲区数据的问题

    千次阅读 2020-11-22 01:01:14
    C语言scanf输入时缓冲区问题 简单解释 问题程序 #include <stdio.h> int main() { char a; while(1) { scanf("%c",&a); switch(a) { case 'A':printf("85~100\n");break; case 'B':printf("75~84\...
  • 连续两次scanf输入字符型数据时第二个scanf会被跳过。 例: #include <stdio.h> main(){ char A,B; scanf("%c",&A); scanf("%c",&B); printf("A=%c\tB=%c",A,B); return 0; } 原因:输入第...
  • 它应该是这样的:在c中使用scanf和循环输入多个双精度数据,并且没有数组循环输入:2.5 5 3.5 4.5 jfkjk输出:min is 2.5max is 5sum is 15.5average is 3.875该方案被认为它到达一个非数字或一个换行符退出。...
  • C语言从键盘输入数据程序是人机交互的媒介,有输出必然也有输入。在C语言中,有多个函数可以键盘获得用户输入:scanf():和 printf() 类似,scanf() 可以输入多种类型的数据。getchar()、getche()、getch():这三...
  • java中实现从键盘读入的方法发布时间:2020-06-18 13:36:00来源:亿速云阅读:119作者:鸽子一、java不像C中拥有scanf这样功能强大的函数,大多是通过定义输入输出流对象。常用的类有BufferedReader,Scanner。1、...
  • 关于scanf接受键盘输入的细节

    千次阅读 2015-08-23 23:06:45
    当键盘输入 a-->回车 后输出的结果是 0,0,a,10 为什么会出现这样的结果呢? 因为   scanf ( "%d" ,&a);   scanf ( "%d" ,&b); 缓存里面存放的是字符(空格和回车除外),...
  • 其功能是按照指定的格式接收由键盘输入数据,并存入输入项变量所在的内存单元中。其中的格式控制字符串构成的内容与printf()函数类似,包含格式说明和普通字符。输入项表中的各输入项逗号隔开,各输入项必须为...
  • 今天做实验,只能vs,奈何scanf它不允许使用,可把我急得啊,经过n次实验,终于在n+1次知道了这个东西怎么的。也许知识知道一点儿吧。在此记一笔,以免忘记。 代码如下 #include<stdio.h> int main() { ...
  • 3.1scanf()函数输入字符的执行原理3.2读取整数 1.连续输入两个scanf的问题(字符) 1.1问题 连续使用scanf输入有个坑,最后的回车是会留在缓冲区的,会被下面的%c或者%s吃掉,最好后面加getchar()吃掉多余的\n。...
  • 最近老陌偶然论坛的一个帖子里发现了以前忽略了的一个知识点,看了一些资料后不得不感慨自己之前对于 scanf对于 C 的理解实在太浅显了!最后我打算把本次学习所得写出来…… double get_input(void) { double a...
  • //调用scanf函数,并从键盘想数组输入数据#include #include int main() { int x[5]; int i; for(i=0;i;i++) { printf("请输入x[%d]的整数值:",i); scanf("%d",&x[i]); printf("\n"); } for(i=0;i;i...
  • C语言创建一个单链表实现键盘输入数据以及增删查

    千次阅读 多人点赞 2020-10-18 17:14:56
    作为一个编程小白,在这里发表自己的第一篇博客,心里还是有点紧张。...我们都知道,链表是由一个又一个节点构成,每个节点又分为数据域和指针域(eg:p->data/p->next)。 ![在这里插入图片描述](https://img.
  • #include"stdio.h" main() { int a;... //C语言给变量输入数据时,&表示是取地址运算符,&a就是变量a在内存中的起始地址,因int类型为4个字节,所以&a往后4个字节用来保存数据。 ...
  • scanf()输入float型数据时出错

    千次阅读 2013-12-28 18:01:10
    我们这里的是VC++6.0的编译环境,下面我们来讨论一下C语言中用scanf()输入float型数据是出错问题。 >>出错代码例举: >出错代码1(含有结构体): #include struct student { float a[3]; }stu[5]; int main()...
  • 标准库I/O提供了三种缓冲类型:全缓冲,行缓冲,无缓冲 标准IO缓冲类型 何处使用 ...标准输入缓冲区stdin使用行缓冲的方式存储输入(接收写入设备的数据存到缓冲区中),用户存入的数据先存在临时

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 33,763
精华内容 13,505
关键字:

当用scanf从键盘输入数据时