-
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 的功能正好相反。
我们先来看一个例子:- #include <stdio.h>
- int main()
- {
- int a = 0, b = 0, c = 0, d = 0;
- scanf("%d", &a); //输入整数并赋值给变量a
- scanf("%d", &b); //输入整数并赋值给变量b
- printf("a+b=%d\n", a+b); //计算a+b的值并输出
- scanf("%d %d", &c, &d); //输入两个整数并分别赋值给c、d
- printf("c*d=%d\n", c*d); //计算c*d的值并输出
- return 0;
- }
运行结果:
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("%d %d", &a, &b); // 获取用户输入的两个整数,分别赋值给变量 a 和 b
- printf("%d %d", a, b); // 将变量 a 和 b 的值在显示器上输出
它们都有格式控制字符串,都有变量列表。不同的是,scanf 的变量前要带一个
&
符号。&
称为取地址符,也就是获取变量在内存中的地址。
在《数据在内存中的存储》一节中讲到,数据是以二进制的形式保存在内存中的,字节(Byte)是最小的可操作单位。为了便于管理,我们给每个字节分配了一个编号,使用该字节时,只要知道编号就可以,就像每个学生都有学号,老师会随机抽取学号来让学生回答问题。字节的编号是有顺序的,从 0 开始,接下来是 1、2、3……
下图是 4G 内存中每个字节的编号(以十六进制表示):
这个编号,就叫做地址(Address)。int a;
会在内存中分配四个字节的空间,我们将第一个字节的地址称为变量 a 的地址,也就是&a
的值。对于前面讲到的整数、浮点数、字符,都要使用 & 获取它们的地址,scanf 会根据地址把读取到的数据写入内存。
我们不妨将变量的地址输出看一下:- #include <stdio.h>
- int main()
- {
- int a='F';
- int b=12;
- int c=452;
- printf("&a=%p, &b=%p, &c=%p\n", &a, &b, &c);
- return 0;
- }
输出结果:
&a=0x18ff48, &b=0x18ff44, &c=0x18ff40%p
是一个新的格式控制符,它表示以十六进制的形式(带小写的前缀)输出数据的地址。如果写作%P
,那么十六进制的前缀也将变成大写形式。
图:a、b、c 的内存地址注意:这里看到的地址都是假的,是虚拟地址,并不等于数据在物理内存中的地址。虚拟地址是现代计算机因内存管理的需要才提出的概念,我们将在《 C语言和内存》专题中详细讲解。
再来看一个 scanf 的例子:
- #include <stdio.h>
- int main()
- {
- int a, b, c;
- scanf("%d %d", &a, &b);
- printf("a+b=%d\n", a+b);
- scanf("%d %d", &a, &b);
- printf("a+b=%d\n", a+b);
- scanf("%d, %d, %d", &a, &b, &c);
- printf("a+b+c=%d\n", a+b+c);
- scanf("%d is bigger than %d", &a, &b);
- printf("a-b=%d\n", a-b);
- return 0;
- }
运行结果:
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() 的要求,要么继续等待用户输入,要么就干脆读取失败,上面我们演示了“继续等待用户输入”的情形,下面我们对代码稍作修改,演示“读取失败”的情形。- #include <stdio.h>
- int main()
- {
- int a = 1, b = 2, c = 3, d = 4; //修改处:给变量赋予不同的初始值
- scanf("%d", &a);
- scanf("%d", &b);
- printf("a=%d, b=%d\n", a, b);
- scanf("%d %d", &c, &d);
- printf("c=%d, d=%d\n", c, d);
- return 0;
- }
运行结果:
12 60 a10↙
a=12, b=60
c=3, d=4前两个整数被正确读取后,剩下了 a10,而第三个 scanf() 要求输入两个十进制的整数,a10 无论如何也不符合要求,所以只能读取失败。输出结果也证明了这一点,c 和 d 的值并没有被改变。
这说明 scanf() 不会跳过不符合要求的数据,遇到不符合要求的数据会读取失败,而不是再继续等待用户输入。
总而言之,正是由于缓冲区的存在,才使得我们能够多输入一些数据,或者一次性输入所有数据,这可以认为是缓冲区的一点优势。然而,缓冲区也带来了一定的负面影响,甚至会导致很奇怪的行为,请看下面的代码:- #include <stdio.h>
- int main()
- {
- int a = 1, b = 2;
- scanf("a=%d", &a);
- scanf("b=%d", &b);
- printf("a=%d, b=%d\n", a, b);
- return 0;
- }
输入示例:
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() 还可以输入单个字符、字符串、小数等,请看下面的演示:
- #include <stdio.h>
- int main()
- {
- char letter;
- int age;
- char url[30];
- float price;
- scanf("%c", &letter);
- scanf("%d", &age);
- scanf("%s", url); //可以加&也可以不加&
- scanf("%f", &price);
- printf("26个英文字母的最后一个是 %c。\n", letter);
- printf("C语言中文网已经成立%d年了,网址是 %s,开通VIP会员的价格是%g。\n", age, url, price);
- return 0;
- }
运行示例:
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() 读取字符串时以空格为分隔,遇到空格就认为当前字符串结束了,所以无法读取含有空格的字符串,请看下面的例子:- #include <stdio.h>
- int main()
- {
- char author[30], lang[30], url[30];
- scanf("%s %s", author, lang);
- printf("author:%s \nlang: %s\n", author, lang);
- scanf("%s", url);
- printf("url: %s\n", url);
- return 0;
- }
运行示例:
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输入字符型数据时,输入的格式要注意什么?
2021-05-19 09:02:21用scanf输入字符型数据时,输入的格式要注意什么?使用时应注意的问题:要求在程序运行中输入数据,输入的数据个数和类型必须与格式说明符一一对应。地址参数形式:&变量名(除数组或指针变量)格式控制中有...用scanf输入字符型数据时,输入的格式要注意什么?
使用时应注意的问题:要求在程序运行中输入数据,输入的数据个数和类型必须与格式说明符一一对应。地址参数形式:&变量名(除数组或指针变量)格式控制中有普通字符时,必须照原样输入。格式控制中无普通字符时,输入的数值型数据和字符串用空白符分隔,字符型数据不必分隔。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
-
第四章 C语言输入输出_C语言scanf:读取从键盘输入的数据(含输入格式汇总表)
2022-02-19 15:08:40从键盘输入12,按下回车键,scanf() 就会读取输入数据并赋值给变量 a;本次输入结束,接着执行下一个 scanf() 函数,再从键盘输入 60,按下回车键,就会将 60 赋值给变量 b,都是同样的道理。 第 8 行代码中,scanfscanf()函数
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:读取从键盘输入的数据(含输入格式汇总表)
2019-04-02 18:23:37程序是人机交互的媒介,有输出必然也有输入,第三章我们讲解了如何将数据输出到显示器上,本章我们开始讲解如何从键盘输入数据。在C语言中,有多个函数可以从键盘获得用户输入: scanf():和 printf() 类似,scanf... -
【c语言学习2】scanf键盘输入
2021-10-16 23:06:41#define _CRT_SECURE_NO_WARNINGS #include<stdio.h> int main() { ... //输入数据-使用输入函数scanf scanf("%d%d", &num1, &num2);//取地址符& scanf是c语言提供,scanf_s不是标准c... -
C语言学习笔记-----scanf【通过键盘将数据输入到变量中】(两种用法)
2019-06-19 09:40:18功能: 将从键盘输入的字符转化为输入控制符所规定格式的数据,然后存入以输入 参数的值为地址的变量中。 举列演示:&i 表示i的地址,&是一个取地址符 用法二:scanf(“非输入控制符 输入控制符”,... -
c语言:用scanf函数输入数据,举例并分析错误原因
2021-05-22 03:57:23用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函数
2021-05-22 10:05:06C语言键盘输入采集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++这样做,想获得高效率,很繁琐,左值引用... -
vs2019、C语言中从键盘中读取字符,用scanf、scanf_s的区别
2021-03-31 13:57:02在使用Visual Studio 2019进行C语言编程时,有时候需要从键盘读取字符,这时候就要用到scanf()语句。 #include<stdio.h> int main() { char a; scanf("%c", &a); printf("%c \n", a); return 0; } ... -
【C语言】-数据输入-scanf( )和getchar( )
2021-05-21 04:53:09格式化输入函数scanf( )scanf( )功能:按照指定的格式读入键盘上输入的若干个任意类型的数据,存入到argument参数所指向的内存单元,函数返回值为读入并赋给argument的数据个数,出错则返回0。scanf( )使用形式:... -
C语言中Scanf( )函数使用注意事项,Scanf 录入不同类型数据时的区别
2020-06-01 13:06:581、 使用sanf( )函数,要包含一个头文件<stdio.h> 2、scanf函数是一个阻塞式函数:函数执行...如果我们的一次输入全都是%d类型的,那么无论我们在输入数据时,之间插入 空格、回车、 Tab等其它字符都不影响,都会 -
深入理解scanf函数输入时键盘缓冲区
2013-07-24 11:30:15本文从根本上讲解了scanf函数的应用,以及输入时键盘缓冲区的数据形式,相信读完之后你会对scanf有更深一层次的认识。 -
scanf函数读取缓冲区数据的问题
2020-11-22 01:01:14C语言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输入字符型数据时,出现跳过输入问题
2018-11-28 21:47:35当连续两次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和循环输入多个双精度数据,并且没有数组循环
2021-05-22 11:34:49它应该是这样的:在c中使用scanf和循环输入多个双精度数据,并且没有数组循环输入:2.5 5 3.5 4.5 jfkjk输出:min is 2.5max is 5sum is 15.5average is 3.875该方案被认为当它到达一个非数字或一个换行符退出。... -
ch2-7 C语言从键盘输入数据.docx
2021-05-22 18:31:26C语言从键盘输入数据程序是人机交互的媒介,有输出必然也有输入。在C语言中,有多个函数可以从键盘获得用户输入:scanf():和 printf() 类似,scanf() 可以输入多种类型的数据。getchar()、getche()、getch():这三... -
java中实现从键盘读入的方法
2021-02-27 10:49:31java中实现从键盘读入的方法发布时间: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); 当缓存里面存放的是字符(空格和回车除外),... -
(二)C语言——数据输入语句scanf()函数
2021-02-05 16:54:48其功能是按照指定的格式接收由键盘输入的数据,并存入输入项变量所在的内存单元中。其中的格式控制字符串构成的内容与printf()函数类似,包含格式说明和普通字符。输入项表中的各输入项用逗号隔开,各输入项必须为... -
scanf_s关于字符串,以及从键盘输入的操作(vs编译器)
2019-11-29 20:06:15今天做实验,只能用vs,奈何scanf它不允许使用,可把我急得啊,经过n次实验,终于在n+1次知道了这个东西怎么用的。也许知识知道一点儿吧。在此记一笔,以免忘记。 代码如下 #include<stdio.h> int main() { ... -
关于scanf读入的细节问题
2021-08-22 18:35:513.1scanf()函数输入字符时的执行原理3.2读取整数时 1.连续输入两个scanf的问题(字符) 1.1问题 连续使用scanf输入有个坑,最后的回车是会留在缓冲区的,会被下面的%c或者%s吃掉,最好后面加getchar()吃掉多余的\n。... -
【C】学习笔记:scanf与键盘输入缓冲区
2020-04-19 10:53:13最近老陌偶然从论坛的一个帖子里发现了以前忽略了的一个知识点,看了一些资料后不得不感慨自己之前对于 scanf对于 C 的理解实在太浅显了!最后我打算把本次学习所得写出来…… double get_input(void) { double a... -
调用scanf函数,并从键盘想数组输入数据
2013-07-30 22:52:11//调用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)。 
2020-06-24 18:56:10#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()... -
scanf是怎么从缓冲区读取数据的?
2021-01-29 15:45:53标准库I/O提供了三种缓冲类型:全缓冲,行缓冲,无缓冲 标准IO缓冲类型 何处使用 ...标准输入缓冲区stdin使用行缓冲的方式存储输入(接收写入设备的数据存到缓冲区中),用户存入的数据先存在临时