当我们需要给变量输入值时,就可以用到scanf
1· 用于读取用户在键盘上的输入(注:标准输⼊⼀般指的就是键盘,标准输出⼀般指的就是屏幕)
简单的说:
当程序运行到这个语句时就会停止,等用户在键盘上输入后,用户按下回车键,scanf()
函数就会处理,将用户的输入存入变量中。
2· scanf()
函数的头文件是stdio.h
(用法与printf
类似)
3· 它的第一个参数是⼀个格式字符串,⾥⾯会放置占位符,告诉编译器用户想要提取的数据类型是什么。它的其余参数就是存放⽤⼾输⼊的变量,格式字符串⾥⾯有n个占位符,就有n个变量。
例子说明:
scanf("%d",&a);
这里的第一个参数是%d
,用户此时应该输入整数,%d
是一个占位符,%
是占位符的标志,d
是整数。第二个参数是&a
,用户输入的数储存在变量中。
注意:&a
传递的是a的地址,变量a的地址指向用户的值,在变量前必须要加上&
(传址),如果这里是指针变量(例如字符串)就不需要用到&
scanf()
处理数值占位符时,会⾃动过滤空⽩字符,包括空格、制表符、换⾏符等。
所以,用户在键盘上输入数据之间有一个或多个空格,或者按回车键将输入分成几行,都不会影响scanf()
函数的读取。
例如:
20
30
4
10
36 48 57 38 47
以上在这么输入都不会影响scanf()
函数解读数据。
scanf()
处理⽤⼾输⼊的原理是:
用户的输⼊先放⼊缓存,等到按下回⻋键后,按照占位符对缓存进⾏解读。解读用户输⼊时,会从上⼀次解读遗留的第⼀个字符开始,直到读完缓存,或者遇到第⼀个不符合条件的字符为止。
示例:
# include
int main ()
{
int a;
float b;
scanf ("%d",&a);
printf ("%d\n",a);
scanf ("%f",&b);
printf ("%f\n",b);
return 0;
}
用户输入:-123.345#@14226
程序运行到第一个scanf()
时,读取用户的输入,%d
占位符会自动忽略掉首位起⾸的空格(我们这里输入的数据没有输入空格),从-
号开始读取,%d
是整数,读取完-123
后不在读取,因为.
不属于整数的范围,所以 printf ("%d\n",a);
输出-123
;调用第二个scanf()
时,从上次停止的地方开始,也就是从.
开始,读取到#
停止,这里是输出浮点型的数,#
不属于浮点型的范围,所以printf ("%d\n",b);
输出0.345000
(浮点型小数点后面规定有六位)
综上,输出结果是:
-123
0.345000
上面的例子,也可以这样写:
# include
int main ()
{
int a;
float b;
scanf ("%d%f",&a,&b);
printf ("%d\n",a);
printf ("%f\n",b);
return 0;
}
scanf
的返回值scanf()
的返回值是⼀个整数,表示成功读取的变量个数。
如果没有读取任何项,或者匹配失败,则返回0
。
如果在成功读取任何数据之前,发⽣了读取错误或者遇到读取到⽂件结尾,则返回常量EOF
(-1)。
例子:
# include
int main()
{
int a,b,c;
a=0;
b=0;
c=0;
float d = 0.0f;
int e = scanf ("%d%d%d%f",&a,&b,&c,&d);
printf("a=%d,b=%d,c=%d,d=%f\n",a,b,c,d);
printf("e=%d\n",e);
return 0;
}
用户输入:1 2 3 4.123
输出就是:
a=1,b=2,c=3,d=4.123000
e=4
这里的e
的值就是scanf()
表示成功读取的变量个数。
(可以自己下去输入,1 2 3 #,那么e的值是3,#不是float
的范围)
• %c
:字符。
• %d
:整数。
• %f
: float
类型浮点数。
• %lf
: double
类型浮点数。
• %Lf
:long double
类型浮点数。
• %s
:字符串。
• %[]
:在⽅括号中指定⼀组匹配的字符(比如 %[0-9]
),遇到不在集合之中的字符,匹配将会停止。
(注:%c
总是返回当前第一个字符,无论该字符是不是空格,所以%c
不会忽略空白字符)
例如:
# include
int main ()
{
char a1=0;
char a2=0;
char a3=0;
scanf("%c%c%c",&a1,&a2,&a3);
printf("%c %c %c\n",a1,a2,a3);
return 0;
}
如果我输入: abc
(abc前面有一个空格)
则输出:
a b
(a1=空格,a2=a, a3=b)
如果要强制跳过字符前的空白字符,可以写成scanf(" %c",&ch)
,在%c
前加一个空格,可以跳过一个或多个空白字符。
例如将上面那个例题正常输出:
# include
int main ()
{
char a1=0;
char a2=0;
char a3=0;
scanf(" %c%c%c",&a1,&a2,&a3); //在%c前面加上一个空格
printf("%c %c %c\n",a1,a2,a3);
return 0;
}
此时输入 abc
输出的结果是:
a b c
%s
:从当前第⼀个非空白字符开始读起,直到遇到空⽩字符(即空格、换⾏符、制表符等)为⽌。
只能读取连续的字符,中间不能有空格,除非多个%s
一起使用
例如:
# include
int main()
{
char arr1[200]={0};
char arr2[200]={0};
scanf("%s %s",arr1,arr2);
printf("%s %s\n",arr1,arr2);
return 0;
}
输入hello world
会输出:
hello world
如果只有一个char arr1[200]={0}
,那么输入hello world
遇到中间的空格就会停止,也就是说,输出只有hello
。
scanf()
遇到%s
占位符,会在字符串变量末尾存储⼀个空字符 \0
。
为了避免用户不符合格式规定的输入。
例如:
# include
int main()
{
int year=0,month = 0,day =0;
scanf("%d-%d-%d",&year,&month,&day);
printf("%d-%d-%d",year,month,day);
return 0;
}
这个代码就规定了用户只能输入格式是几年—几月—几号,如果用户格式输入不对,那么输出结果就有问题。
如果我们输入2024\1\22
。那么输出的结果就是2024-0-0
,就不是我们想要的结果。
因此,scanf()
提供了⼀个赋值忽略符。只要把 * 加在任何占位符的百分号后面,该占位符就不会返回值,解析后将被丢弃。
# include
int main()
{
int year=0,month=0,day=0;
scanf("%d%*c%d%*c%d%*c",&year,&month,&day);//为什么是用c,因为-也是一个字符
printf("%d-%d-%d",year,month,day);
return 0;
}
此时,用户不管输入代码形式,输出的结果都是几年—几月—几号
例如输入2024\1\22或者2024 1 22
,结果都是2024-1-22
。