(1)简介:
scanf函数是c语言当中非常重要的格式化输入函数
其函数原型为:int scanf(const char *format, ...);
其函数返回值:成功格式化解析的个数
其调用格式为:scanf("<格式化字符串>", <参量表>);
(2)转换说明:
转换格式为:%[*][宽度][类型长度]类型
除了最后的类型之外都是可选的字段
修饰符 | 意义 |
* | 滞后赋值;示例:"%*d" |
digit(s) | z最大字段宽度;在达到最大字段宽度或者遇到第一个空白字符时(不管哪个先发生都一样)停止对输入项的读取;示例:"%10s" |
hh | b把整数读作signed char或unsigned char;示例:"%hhd" "%hhu" |
ll | b把整数读作long long或unsigned long long(c99);示例:"%lld" "%llu" |
h,l或L | "%hd"和"%hi"指示该值将会储存在一个short int中。"%ho"、"%hx"和"%hu"指示该值将会储存在一个unsigned short int中。"%ld"和"%li"指示该值将会储存在一个long中。"%lo"、"%lx"和"%lu"指示该值将会储存在一个unsigned long中。"%le"、"%lf"和"%lg"指示该值以double类型储存。将L(而非l)与e、f和g一起使用指示该值以long double类型储存。如果没有这些修饰符,d、i、o和x指示int类型,而e、f和g指示float类型; |
转换说明符 | 意义 |
%c | 把输入解释称一个字符 |
%d | 把输入解释称一个有符号十进制整数 |
%e,%f,%g,%a | 把输入解释称一个浮点数(%a是c99标准) |
%E,%F,%G,%A | 把输入解释称一个浮点数(%A是c99标准) |
%i | 把输入解释称一个有符号十进制整数 |
%o | 把输入解释称一个有符号八进制整数 |
%p | 把输入解释称一个指针(一个地址) |
%s | 把输入解释称一个字符串,输入内容以第一个非空白字符作为开始,并且包含直到下一个空白字符的全部字符 |
%u | 把输入解释称一个无符号十进制整数 |
%x,%X | 把输入解释称一个无符号十六进制整数 |
[] | 字符集合 |
(3)高级用法:
网上已经有很多博客将scanf的常用方法说的非常详细了,本篇博客不再详细介绍。
1。捕获规则
在出现一个转换说明符时,scanf函数会忽略前面的所有空白字符(除了%c),然后再捕获相应的数据类型,一直到最大长度或者出现空白字符
scanf("%d,%d", &a, &b);
允许的输入格式为:1,2\n;1, 2\n;1,\n2\n;
不允许的输入格式:1 ,2\n; \n1,2\n; 1,2\n;
2。%[] 字符集合
这个算scanf函数中比较高级一点的用法
[]里面填写需要捕获的字符集合,例如
char buf[20];
scanf("%[abc]", buf); //输入abcdabcd123, buf内容为abc
scanf函数匹配[]中的所有字符,直到找到一个非[]中的字符
[]中也可以填写字符范围,例如
[a-z] //捕获包括字符从a到z的所有字符,直到找到一个非a-z的字符
[a-zA-Z] //捕获所有字母
[0-9] //捕获所有数字
[a-zA-Z0-9]捕获所有字母和数字
[a-zA-Z0-9!]捕获所有字母和数字并且捕获!(感叹号)
[]中如果第一字符为^符号则表示出现[]中的内容则停止捕获,例如
[^a-zA-Z]捕获非字母
[^0-9]捕获非数字
3。scanf中的空格和\n
scanf中的空格的作用不仅仅是捕获一个空格,它表示捕获所有空白字符(空格,换行,制表符等)直到出现一个非空白字符(\n一样),例如
我们想接受一个ip:端口的输入
需要接受的输入格式为:ip:端口,ip: 端口,ip : 端口,ip\n:\n端口
如果代码为scanf("%d.%d.%d.%d:%d", &ip[0], &ip[1], &ip[2], &ip[3], &port);
则只能捕获的格式:ip:端口,ip: 端口,ip:\n端口
如果我们将代码改为scanf("%d.%d.%d.%d :%d", &ip[0], &ip[1], &ip[2], &ip[3], &port); // : 前面多了一个空格
则可以捕获上述所有情况
4。scanf中的混合输入字符和数字
在scanf当中混合输入字符和数字是一个比较烦人的问题
如果我们直接编写代码为
1 #include <stdio.h> 2 3 int main() { 4 char ch; 5 int num; 6 7 while(scanf("%c%d", &ch, &num) == 2) { 8 printf("*%c*, *%d*\n", ch, num); 9 } 10 return 0; 11 }
第一次scanf("%c%d");没有任何问题
第二次scanf("%c%d");字符会将上一次的\n给解析进来,就会出现了问题
解决方案1:
#include <stdio.h> int main() { char ch; int num; while(scanf("%c%d", &ch, &num) == 2) { printf("*%c*, *%d*\n", ch, num); while(getchar() != ‘\n‘); //清除上次输入残留的\n } return 0; }
解决方案2:
#include <stdio.h> int main() { char ch; int num; while(scanf(" %c%d", &ch, &num) == 2) { //前面加一个空格忽略所有空白字符 printf("*%c*, *%d*\n", ch, num); } return 0; }
未定义的方案(官方文档未定义,勿用):
#include <stdio.h> int main() { char ch; int num; while(scanf("%c%d", &ch, &num) == 2) { printf("*%c*, *%d*\n", ch, num); fflush(stdin); //flush标准输入流 } return 0; }
原文地址:https://www.cnblogs.com/windpiaoxue/p/9184194.html