scanf函数详细讲解

(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;
}

 

posted @ 2018-06-14 17:42  wind飘雪  阅读(15998)  评论(0编辑  收藏  举报