用于,给变量输入值
#include <stdio.h>
int main()
{
int score = 0;//成绩
printf("请输入一个值:");
scanf("%d", &score); //& 取地址操作符
printf("score = %d\n", score);
return 0;
}
注意:
如果此时使用的是VS,则会报错
意思为: scanf函数可能是不安全的,考虑使用scanf_s函数来替代
scanf_s函数是VS种msvc这个编译器提供的函数,不是C语言本身的库函数
如果在代码中使用scanf_s函数,那这个代码只能在VS上编译,不具有跨平台性
解决办法:使用_CRT_SECURE_NO_WARNINGS
将:
#define _CRT_SECURE_NO_WARNINGS 1
放到代码的第一行(#include之前),1可以省略
- 如果每次使用scanf函数时都要加这个代码,会比较繁琐,下面介绍一个一劳永逸的办法:
目标:在创建.c文件的时候,自动在第一行加上这句话
原理:.c/.cpp的文件在新建的时候,都是拷贝了一个文件 newc++file.cpp
故应在该文件的第一行加上这句话,那么产生的新文件中就会自动有这个代码
1.使用everything,查找newc++file.cpp
2.单击鼠标右键,找到打开路径,找到这个文件
3.单击右键,找到在记事本中编辑
4.将这句代码放入即可
也可以在VS中打开
CTRL+S保存
保存
是
没有权限
此时,CTRL+C拷贝newc++file.cpp这个文件,将它放到桌面上
再将其用VS打开,添加那句代码,保存
但是此时这个文件还在桌面上,应当将其拷贝回去
替换成功之后,就会变为1KB
重新打开VS即可
如果在新建项的时候需要这一语句,需要 显示所有模板,否则没有
接下来我们回到对scanf()的说明:
例:
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main() {
char arr[5];
scanf("%s",arr);//arr是数组名,数组名就是地址
printf("%s",arr);
return 0;
}
- 输入一个少于五个字符的字符串:
- 输入一个多于五个字符的字符串:
如果输入的字符串太长,arr无法存储,scanf依然会将数据存放在arr中,就可能存在非法访问内存
scanf的基本用法
scanf()函数用于读取用户的键盘输入。
程序运行到这个语句时,会停下来,等待用户从键盘输入
用户输入数据按下回车键后, scanf( )就会处理用户的输入,将其存入变量。
它的原型定义在头文件 stdio.h
scanf()的语法跟printf()类似
int i=e;
scanf("%d",&i);|
它的第一个参数是一个格式字符串,里面会放置占位符(与printf()的占位符基本一致),告诉编译器如何解读用户的输入,需要提取的数据是什么类型
这是因为C语言的数据都是有类型的,scanf()必须提前知道用户输入的数据类型,才能处理数据
它的其余参数就是存放用户输入的变量,格式字符串里面有多少个占位符,就有多少个变量
注意:变量前面必须加上&运算符(指针变量除外),因为 scanf()传递的不是值,而是地址,即将变量i的地址指向用户输入的值. 如果这里的变量是指针变量(比如字符串变量),那就不用加&运算符。
读取多个值:
scanf("%d%d%f%f", &m,&n,&x,&y);
上面示例中,格式字符串 %d%d%f%f,表示用户输入的前两个是整数,后两个是浮点数这四个值依次放入m,n、x、y四个变量
scanf() 处理数值占位符时,会自动过滤空白字符,包括空格、制表符、换行符等。
所以,用户输入的数据之间,有一个或多个空格不影响scanf()解读数据
另外,用户使用回车键,将输入分成几行,也不影响解读
每次按下回车键以后,scanf()就会开始解读,如果第一行匹配第一个占位符,那么下次按下回车键时,就会从第二个占位符开始解读
scanf()处理用户输入的原理是,用户的输入先放入缓存,等到按下回车键后,按照占位符对缓存进行解读。解读用户输入时,会从上一次解读遗留的第一个字符开始,直到读完缓存,或者遇到第一个不符合条件的字符为止
#include <stdio.h>
int main()
{
int x;
float y;
//用户输入" -13.34e12# 0"
scanf("%d", &x);
printf("%d\n", x);
scanf("%f", &y);
printf("%f\n", y);
return 0;
}
输出如下:
为什么会出现这种输出呢?
因为x是整数,所以读到.就会停止,故x里为-13
从上一次读到的位置继续往右走
因为y是浮点数,所以读到#时就会停止
scanf的返回值
scanf()的返回值是一个整数,表示成功读取的变量个数
如果没有读取任何项,或者匹配失败,则返回0
如果在成功读取任何数据之前,发生了读取错误或者遇到读取到文件结尾,则返回常量EOF(-1)
EOF - end of file文件结束标志
#include <stdio.h>
int main()
{
int a=0;
int b=0;
float f = 0.0f;
int r = scanf("%d %d %f",&a,&b, &f);
printf("a=%d b=%d f=%f\n",a,b,f);
printf("r = %d\n",r);
return 0;
}
输入输出测试:
输入:2 3 #
输出:
f为浮点数,但是输入了#,#没有被读取,故scanf返回值为2
输入:3个CTRL+Z(VS中)
输出:读取失败
要想让scanf在读取任何数据之前,就读取失败,按CTRL+Z
在**Devc++**中,输入一个CTRL+Z即可
多组输入的题目中,会使用到scanf的返回值
scanf()的占位符
scanf()的占位符和printf()的占位符基本一致
常用的占位符:
- %c:字符
%d:整数
%f:float类型浮点数
%lf: double 类型浮点数
%Lf: long double类型浮点数
%s: 字符串。
%[ ]:在方括号中指定一组匹配的字符(比如%[0-9]),遇到不在集合之中的字符,匹配将会停止
上面所有占位符之中,除了%c以外,都会自动忽略起首的空白字符
%c 不忽略空白字符,总是返回当前第一个字符,无论该字符是否为空格
如果要强制跳过字符前的空白字符,可以写成 scanf(" %c",&ch) ,即%c前加上一个空格,表示跳过零个或多个空白字符
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
int main()
{
char a= 0;
scanf("%c", &a);
printf("---%c---\n", a);
return 0;
}
此时读取的是第一个空格
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
int main()
{
char a= 0;
scanf(" %c", &a);//在%c前加一个空格,可以在读取到有效字符之前,跳过前面的空格
printf("---%c---\n", a);
return 0;
}
此时读取到的是x
%s不能简单地等同于字符串
它的规则是,从当前第一个非空白字符开始读起,直到遇到空白字符(即空格、换行符、制表符等)为止
因为%s不会包含空白字符,所以无法用来读取多个单词,除非多个%s一起使用。这也意味着,scanf()不适合读取可能包含空格的字符串
另外,scanf()遇到%s占位符,会在字符串变量末尾存储一个空字符\0
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
int main()
{
char arr[20];
scanf(" %s", arr);
printf("%s\n", arr);
return 0;
}
没有空格时:
abcdef\0
有空格时:
abc\0
scanf() 将字符串读入字符数组时,不会检测字符串是否超过了数组长度。所以,储存字符串时,很可能会超过数组的边界,导致预想不到的结果
为了防止这种情况,使用%s占位符时,应该指定读入字符串的最长长度,即写成 %[m]s
[m]是一个整数,表示读取字符串的最大长度,后面的字符将被丢弃
#include <stdio.h>
int main()
{
char name[11];
scanf("%10s",name);
return 0;
}
上面示例中,name是一个长度为11的字符数组,scanf()的占位符%10s表示最多读取用户输入的10个字符,后面的字符将被丢弃,这样就不会有数组溢出的风险了
赋值忽略符
有时,用户的输入可能不符合预定的格式
#include <stdio.h>
int main()
{
int year =0;
int month =0;
int day = 0;
scanf("%d%d%d",&year, &month,&day);
printf("%d/%d/%d\n", year, month,day);
return 0;
}
输入格式正确:
输入格式错误:
因为year,month,day都是整型,所以在读取到/时就已经停止了,/后面内有被读取到,所以month和day都为0
另一个例子:
#include <stdio.h>
int main()
{
int year =0;
int month =0;
int day = 0;
scanf("%d,%d,%d",&year, &month,&day); //在各个输入之间加,
printf("%d/%d/%d\n", year, month,day);
return 0;
}
错误输入:
正确输入:
scanf函数中指定的格式,要和输入的数据的格式严格匹配才可以正确读取数字
为了避免这种情况,scanf()提供了一个赋值忽略符(assignment suppression character).
只要把*加在任何占位符的百分号后面,该占位符就不会返回值,解析后将被丢弃
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
int main()
{
int year = 0;
int month = 0;
int day = 0;
scanf("%d%*c%d%*c%d", &year, &month, &day);
printf("%d/%d/%d\n", year, month, day);
return 0;
}
%*c就是在这个占位符的百分号后面,加入了赋值忽略符 *,表示这个占位符没有对应的变量,解读后不必返回
ps:又到周末啦!开心
制作不易,继续关注博主,跟着博主一起学习吧!
最后:
**
“以清净心看世界,以欢喜心过生活,
以平常心生情味,以柔软心除挂碍。
“没有销声匿迹,我在,热爱生活~ ”
**