By francis_hao    Aug 26,2017

 

scanf – 输入格式转换

 

概述

#include <stdio.h>
int scanf(const
char
*format,
...);

 

描述

该函数通过format扫描标准输入stdin, format包含转换描述说明,如果需要转换,那么转换后的结果存储在format之后的指针参数中,每个指针参数类型必须要正确对应转换说明。如果format中转换说明符的个数,超过了后面的指针参数,那么结果将是未定义的。反过来,如果指针参数的数量超过了转换符的数量,那么多余的指针参数将被忽略。

format字符串包含一串指令,这些指令描述了该如何处理输入的字符,如果一个指令处理失败,那么之后的输入将不再读取,而且函数返回。处理失败可以是以下几种:
1、输入失败,意味着输入的字符串不可用。
2、匹配失败,意味着输入不相称。

一个指令可以是下面几种:
1、一串空白符(空格,tab,新行等),此指令匹配任何数量的空白符,也可以匹配none。
2、普通的字符(既不是空白字符也不是'%')。这种字符必须准确的匹配输入的字符。
3、以'%'开头的转换说明,通过此说明将输入的字符串进行转换,结果会放在对应的指针参数中,如果输入的项与转换说明不匹配,那么转换就会失败,这就是上面提到的匹配失败。

format中的转换说明以'%'或"%n$"开始,后面(按顺序)跟着以下内容:
1、一个可选的'*'分配抑制符,scanf()像普通的转换符那样从输入读取,但是之后会丢弃该输入,不会将该输入存入指针参数,而且不会作为scanf()返回的成功分配项的数量。
2、一个可选的'm'字符。此项用于转换符%s,%c和%[,使调用者无需申请存放输入的缓冲,而是由scanf()去申请缓存,并将缓存的地址赋给指针参数,该参数应该是一个指向char *变量(该变量在调用前无需初始化,但是建议仍旧初始化一下)的指针。调用者需要在之后不再需要该缓冲的时候进行free(3)。
3、一个可选的十进制整数,用来指定字段最大宽度。此项表示当读取到了指定的最大宽度或读取到不匹配的字符后就会停止,。大部分的转换符会跳过前面的空白字符(例外情况在下面介绍),而且那些跳过的字符不计入最大字段宽度,字符串输入转换符包含一个终止字节'\0'以表示输入的结束,字段最大宽度也不包括此项。
4、一个可选的,类型修饰符,例如,修饰符l用于转换符%d表示其对应的指针参数指向一个long int类型而不是一个int类型。
5、转换说明符,用以指定输入需要转换的类型。

format中的转换说明有两种形式,要么以'%'开始,要么以"%n$"开始。两种形式不能在同一个format中混用,但是有"%n$"的转换说明可以包含%%和%*。如果format包含'%'说明,那么参数会按顺序,一个个的进行赋值。但是在"%n$"形式中(此形式是POSIX.1-2001指定的,不是C99),其中n是一个十进制整数,用以指定被转换后的输入应该存放在第n个指针参数处。

类型修饰符

类型修饰符

说明

h

表明转换符将是d,i,o,u,x,X或n的其中一个,而且其后的参数是一个指向short int或unsigned short int(而不是int)的指针。

hh

类似h,但是其后的参数是一个指向signed char 或 unsigned char的指针

j

类似h,但是其后的参数是一个指向intmax_t 或 uintmax_t的指针

t

类似h,但是其后的参数是一个指向ptrdiff_t的指针

z

类似h,但是其后的参数是一个指向size_t的指针

l

1、表明转换符将是d,i,o,u,x,X或n的其中一个,而且其后的参数是一个指向long int或unsigned long int(而不是int)的指针

2、表明转换符将是e, f,或g的其中一个,而且其后的参数是一个指向double(而不是float)的指针

3、指定两个l,和L一致。

L

1、表明转换符将是e, f, 或 g的其中一个,而且其后的参数是一个指向long double的指针

2、表明转换符是d, i, o, u,或x的其中一个,而且其后的参数是一个指向long double的指针

 

转换符

转换符

说明

d

匹配一个有符号的十进制整数,后面的指针参数必须是一个指向int的指针

i

匹配一个有符号的十进制整数,后面的指针参数必须是一个指向int的指针

输入如果是以0x或0X开头,就以16进制读入

输入如果是以0开头,就以8进制读入

其他形式就以10进制读入

o

匹配一个无符号八进制整数,后面的指针参数必须是指向unsigned int的指针

u

匹配一个无符号十进制整数,后面的指针参数必须是指向unsigned int的指针

x

匹配一个无符号十六进制整数,后面的指针参数必须是指向unsigned int的指针

f,e,E,g,a

匹配一个有符号的浮点数,后面的指针参数必须是指向float的指针

s

匹配一个没有空白字符的字符串序列,其后的指针参数必须是指向字符数组的指针,而且大小要足够大以容纳输入的序列和终止符null字节。当遇到输入的空白字符或者最大字段宽度时即停止。

c

匹配一个字符序列,其长度由最大字段宽度指定(默认是1),其后的指针参数必须是指向char的指针,而且要有足够长的空间存储所有的字符(结尾不会自动添加null字节)。如果开头有空白字符不会跳过,如果想要跳过开头的空白字符,需要在format中使用一个确实的空格。

[

从指定的接受字符集合中匹配一个非空字符序列,后面的指针参数必须是指向char的参数,而且,必须有足够的空间已存放所有匹配的字符和一个终止的null字节。此项中,如果开头有空白字符不会跳过。

[]中的字符组成了一个集合,表示只匹配[]里的字符,如果是开头的字符是^,则表示除了[]内的字符其余的字符集合,如果想包含一个],需要将]放在[或[^后的第一个位置,在其他位置则表示集合终止。-是有特殊含义的,表示一个字符范围,如果想包含-则需要放在[]的最后一个位置。比如

[^]0-9-]:表示除了],0,1,2,3,4,5,6,7,8,9,-这12个字符以外的所有字符。

p

匹配一个指针数值,后面的指针参数必须是指向void的指针

n

不需要输入,而是将截止到该项为止,之前输入的字符数存储在其后对应的指针中,指针参数必须是指向int类型的指针。此项不属于转换符,尽管它可以被*抑制(抑制之后就什么作用都没有了)

返回值

返回函数成功匹配和分配的项数,有可能少于提供的参数,如果最早匹配时发生错误甚至会返回0。

如果在成功转换完成或者匹配失败之前,遇到了输入的结尾,那么就会返回EOF。如果读取失败同样也会返回EOF,并且errno会被置为相应的值。

 

 

示例

1、

结果为

本示例主要说明了分配抑制符*的使用,可以用来过滤掉不需要的输入,因为带*的转换说明不会给其后的参数赋值,因此也不需要给定存储的参数。

而n主要是记录到此前位置共有多少个字符被输入(包含空格),并将该值分配给其后的参数

2、man手册上的一个例子,添加了一些注释

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>

int main(void)
{
    char
*p;
    int n;

    errno =
0;
    n = scanf("%m[a-z]",
&p);
    if
(n ==
1)
{/*number of input items successfully matched and assigned*/
        printf("read: %s\n", p);
        free(p);
    }
else
if
(errno !=
0)
{/*EOF must be returned*/
        perror("scanf");
    }
else
{/*matching failure n may be zero*/
        fprintf(stderr,
"No matching characters.n is %d\n",n);
    }

    return
0;
}

结果为

 

 


本文由 刘英皓 创作,采用 知识共享 署名-非商业性使用-相同方式共享 3.0 中国大陆 许可协议进行许可。欢迎转载,请注明出处:
转载自:http://www.cnblogs.com/yinghao1991/p/7436582.html

 

 

参考

【1】man scanf

scanf函数用法小记的更多相关文章

  1. scanf()函数用法小结

    scanf()函数是格式化输入函数,它从标准输入设备(键盘) 读取输入的信息. 其调用格式为:      scanf("<格式化字符串>",<地址表>); ...

  2. printf函数用法小记

    By francis_hao    Aug 26,2017   C语言中printf函数是一个比较常用的函数,但是常用并不代表完全了解,本文翻译了printf的man手册,介绍了其全部功能(不包括ma ...

  3. ioctl函数用法小记

    By francis_hao    Aug 27,2017   UNPV1对ioctl有算是比较详细的介绍,但是,这些request和后面的数据类型是从哪里来的,以及参数具体该如何使用呢?本文尝试在不 ...

  4. 黑马程序员——C语言基础 scanf函数 基本运算 三目运算符

    Java培训.Android培训.iOS培训..Net培训.期待与您交流! (一下内容是对黑马苹果入学视频的个人知识点总结) (一)scanf函数 1>  简单介绍一下scanf函数   这是在 ...

  5. C语言中关于scanf函数的用法

    scanf()函数的控制串 函数名: scanf 功 能: 执行格式化输入 用 法: int scanf(char *format[,argument,...]); scanf()函数是通用终端格式化 ...

  6. [Keil 学习] printf, scanf函数的用法

    C语言库函数中有一批"标准输入输出函数",它是以标准的输入输出设备(一般为终端设备)为输入输出对象的,其中用得比较多的是printf和scanf函数了. 在嵌入式设备中加入C语言的 ...

  7. 4-printf & scanf函数

    一.printf函数 这是(printf和scanf)在stdio.h中声明的一个函数,因此使用前必须加入#include <stdio.h> 1.用法 1> printf(字符串) ...

  8. scanf函数

    一. 变量的内存分析 1. 字节和地址 为了更好地理解变量在内存中的存储细节,先来认识一下内存中的“字节”和“地址”. 1> 内存以“字节为单位” 0x表示的是十六进制,不用过于纠结,能看懂这些 ...

  9. 【C语言】05-printf和scanf函数

    一.printf函数 这是在stdio.h中声明的一个函数,因此使用前必须加入#include <stdio.h>,使用它可以向标准输出设备(比如屏幕)输出数据 1.用法 1> pr ...

随机推荐

  1. 【system.file】使用说明

    对象:system.file 说明:提供一系列针对文件操作的方法. 注意:参数中的filePath 均为相对网站根目录路径 目录: 方法 返回 说明 system.file.exists(filePa ...

  2. Python全栈 Web(概述、HTML基础语法)

    原文地址: https://yq.aliyun.com/articles/631222 ........................................................ ...

  3. 垃圾收集器与内存分配策略(深入理解Java虚拟机)

    3.1 概述 垃圾收集器要解决哪些问题? 哪些内存需要回收 什么时候回收 如何回收 引用计数算法:当有一个地方引用,+1,引用失效,-1.     缺点:对象之间相互循环引用的问题. 可达性分析算法: ...

  4. lintcode39 恢复旋转排序数组

    恢复旋转排序数组   给定一个旋转排序数组,在原地恢复其排序. 您在真实的面试中是否遇到过这个题? Yes 说明 什么是旋转数组? 比如,原始数组为[1,2,3,4], 则其旋转数组可以是[1,2,3 ...

  5. python图片大小处理;

    循环一个目录将下面的所有png或者jpg文件全部缩小一定比例:     from PIL import Image import os,re work_dir = 'C:\\Users\\Admini ...

  6. OpenMPI 集群配置

    现在有2台机器,希望可以尝试一下在多台机器上跑MPI的感觉,所以跑之前就得配置,先参考网址: https://www.cnblogs.com/awy-blog/p/3402949.html: 1. 配 ...

  7. 聊一聊session

    最近从上家公司离职了,到了一家新公司,这几天一直在了解他们的项目,所以我自己的那个小项目也暂时搁浅了.. 今天差不多把他们的项目了解了,来院子写写我在这里边遇到的问题,影响最深刻的是seesion的. ...

  8. dice2win早期版本

    原理; https://medium.com/dapppub/fairdicedesign-315a4e253ad6 早期版本地址: https://etherscan.io/address/0xD1 ...

  9. Ubuntu14.04下部署FastDFS 5.08+Nginx 1.9.14

      最新的版本可以在这里获取,目前下载的最新版本是5.08,更新于2016-02-03.在这里可以找到更多的说明. 下载好后,server端分为两个部分,一个是tracker,一个是storage.顾 ...

  10. “Hello World”团队第一周博客汇总

    时间:2017-10-13——2017-10-19 Scrum会议: 会议要求博客:https://edu.cnblogs.com/campus/nenu/SWE2017FALL/homework/1 ...