1.前言
前面说过了printf函数 他是将二进制表示的整数、浮点数、字符、字符串根据转换规范转换成字符或者字符串 并且打印到了控制台上 那么既然有了输出函数 那么肯定也有输入函数咯
的确如此 他就是scanf函数 他是将字符或者字符串根据转换规范转换成二进制表示的整数、浮点数、字符、字符串 储存到了相应的变量中
int main(){
char ch;
short s;
int i;
long l;
long long ll;
float f;
double df;
scanf("%hhd %hd %d %ld %lld %f %lf", &ch, &s, &i, &l, &ll, &f, &df);// 65 66 67 68 69 1.23 1.234
printf("%hhd %hd %d %ld %lld %f %lf", ch, s, i, l, ll, f, df);// 65 66 67 68 69 1.230000 1.234000
return 0;
}
2.scanf的注意事项
scanf主要有以下这些注意事项:
1.scanf函数是一个变参函数(变参体现在参数数量和参数类型的不确定)
2.scanf函数的第一个参数是字符串
3.scanf函数的第一个参数的内容是是匹配的字符以及转换规范
4.scanf函数的后续参数是字符或者字符串转换完毕以后存放的位置
5.scanf函数的后续参数的数量和类型要和第一个参数中的转换规范依次对应
上述五点中 我们着重讲一下3、4两点
1.第一个参数内容为匹配字符和转换规范
有什么字符 你要跟着输入什么字符用于匹配
int main(){
int i;
long l;
scanf("%d, %ld", &i, &l);// 1,1
printf("%d %ld", i, l);// 1 1
return 0;
}
2.后续参数为转换完毕以后存放的位置
后续参数记得取的是地址值 所以对于大部分的变量来说需要加&取地址符 但是对于数组名来说 由于他本身为地址的缘故 所以无需加上取地址符
3.scanf函数的具体操作
第一步就是将键入的字符串和第一个参数进行依次匹配
第二步就是根据转换规范将字符或者字符串转换为二进制表示的各种类型
不同的转换规范对应的转换方式如下所示:
第三步就是将转换完毕的二进制数据依次储存到变量中去
4.几类错误案例
1.长度正确但是类型错误
int main(){
long long ll;
scanf("%lf", &ll);
printf("%lld\n", ll);// 4638387438405602509
printf("%lf", ll);// 123.450000
return 0;
}
这个案例中 我们将输入的123.45和%lf进行匹配 匹配成功之后 将其转换为double类型的数据 其占8个字节 然后存储到同为8个字节的long long类型变量中 这样ll就是一个存有double类型数据的整型变量了
接着通过%lld的转换规范进行打印 他的打印结果是截取sizeof(long long)个字节 然后将二进制数据转换为有符号的十进制整型 这与我们所期待的浮点数结果不符 所以结果自然错误打印出来了
但是如果利用%lf这个转换规范进行打印的话 结果自然是被正确打印了
但是最好是不要采用整数来储存浮点数这种做法 而是利用相应的浮点数类型储存较为妥当
2.输入的字符串数值大于转换操作类型的取值范围
int main(){
short s;
scanf("%hd", &s);// 2100000000
printf("%hd", s);// 29952
return 0;
}
2100000000这个数据明显用2个字节的short类型无法承载 所以最后无法正确打印结果
3.变量无法装载转换结果
int main(){
short s;
scanf("%d", &s);// 2100000000
printf("%ld", s);// 29952
return 0;
}
这个数据远远超出了2个字节类型short的承载范围 所以如果用short类型进行承载的话 那么就会丢失2个字节的数据 结果就是无法正确表示这个数据
4.避免以上错误
为了避免以上错误 要求我们在书写scanf函数的时候注意规范
所谓规范就是要保持输入的字符串数值和转换规范以及存放的变量类型要一致才行
5.字符和字符串的输入
刚才我们讨论的都是有关整数和浮点数的输入问题 现在讨论字符和字符串的输入
1.字符的输入
int main(){
char ch;
scanf("%c", &ch);// A
printf("%c %hhd", ch, ch);// A 65
return 0;
}
上述案例中 我输入65和第一个字符串中的%c匹配成功 然后将这个数据转换为二进制表示的字符 然后将其存入ch变量中 我用%c打印出这个变量的字符形式 用%hhd打印出这个变量的整数形式
2.字符串的输入
int main(){
char str[10];
scanf("%s", str);// HelloWorld
printf("%s", str);// HelloWorld
return 0;
}
上述案例中 我输入HelloWorld和第一个字符串中的%s匹配成功 然后将这个数据转换为二进制表示的字符串 然后将其存入str变量中 我用%s将这个字符串打印到控制台中
6.visual studio无法使用scanf
这个问题的解决参考以下步骤:
1.右击指定文件 选择属性
2.选择C/C++中的预处理器 选择预处理器定义中的编辑
3.接着将_CRT_SECURE_NO_WARNINGS添加到其中即可 点击应用关闭
7.printf和scanf函数的不同
1.printf函数的后续参数不需要加上&取地址符 但是scanf函数的后续参数中基本需要添加取地址符 除了数组名以外
2.对于转换规范和后续参数的对应关系中 printf函数的使用是比较松弛的 因为他允许通过%d将char、short、int类型输出 而对于scanf函数来说 他需要严格对应转换规范和后续参数 否则可能会导致削减字节输出错误