scanf, fscanf, sscanf, scanf_s, fscanf_s, sscanf_s
在标头 <stdio.h> 定义
|
||
(1) | ||
int scanf( const char *format, ... ); |
(C99 前) | |
int scanf( const char *restrict format, ... ); |
(C99 起) | |
(2) | ||
int fscanf( FILE *stream, const char *format, ... ); |
(C99 前) | |
int fscanf( FILE *restrict stream, const char *restrict format, ... ); |
(C99 起) | |
(3) | ||
int sscanf( const char *buffer, const char *format, ... ); |
(C99 前) | |
int sscanf( const char *restrict buffer, const char *restrict format, ... ); |
(C99 起) | |
int scanf_s(const char *restrict format, ...); |
(4) | (C11 起) |
int fscanf_s(FILE *restrict stream, const char *restrict format, ...); |
(5) | (C11 起) |
int sscanf_s(const char *restrict buffer, const char *restrict format, ...); |
(6) | (C11 起) |
从各种资源读取数据,按照 format
转译,并将结果存储到指定位置。
stream
读取数据buffer
读取数据。抵达字符串结尾等价于 fscanf
的抵达文件尾条件- 任何指针类型的参数是为空指针
-
format
、stream
或buffer
为空指针 - %c 、 %s 或 %[ 会写入的字符数,加上空终止字符,要超过提供给这些转换指示符的第二个( rsize_t )参数
- 可选,任何其他可检测错误,例如未知转换指示符
- 同所有边界检查函数,
scanf_s, fscanf_s, sscanf_s
仅若实现定义了 __STDC_LIB_EXT1__ ,且用户在包含<stdio.h>
前定义 __STDC_WANT_LIB_EXT1__ 为整数常量 1 才保证可用。
参数
stream | - | 要读取的输入文件流 | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
buffer | - | 指向要读取的空终止字符串的指针 | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
format | - | 指向指定读取输入方式的空终止字符串的指针。
格式字符串由下列内容组成
下列格式指示符可用:
对于每个异于 所有异于 转换指示符 转换指示符 定宽整数类型( 在每个转换指示符后有一个序列点;这允许存储多个域到同一“池”变量中。 在分析以无数字指数为结尾的不完整浮点值,如以转换指示符 %f 分析 "100er" 时,消耗序列 "100e" (可能为合法浮点数的最长前缀),并导致匹配错误(被消耗序列不能转换成浮点数),而留下 "r" 。某些既存实现不遵守此规则并回滚,通过消耗 "100" 而留下 "er" ,例如 glibc 漏洞 1765 。 若转换指示非法,则行为未定义。
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
... | - | 接收用参数 |
返回值
注解
因为多数转换指示符首先消耗掉所有连续空白符,如下的代码
scanf("%d", &a); scanf("%d", &b);
将读取在不同行上(第二个 %d 会消耗第一个剩下的换行符)或同一行由空格或制表符分隔(第二个 %d 会消耗空格或制表符)的整数。
不消耗前导空白符的转换指示符,如 %c ,可以通过在格式字符串中前置一个空白符令它如此:
scanf("%d", &a); scanf(" %c", &c); // 消耗 %d 后的所有后继空白符,然后读一个 char
示例
#define __STDC_WANT_LIB_EXT1__ 1 #include <stdio.h> #include <stddef.h> #include <locale.h> int main(void) { int i, j; float x, y; char str1[10], str2[4]; wchar_t warr[2]; setlocale(LC_ALL, "en_US.utf8"); char input[] = "25 54.32E-1 Thompson 56789 0123 56ß水"; /* 按下列分析: %d :整数 %f :浮点值 %9s :最多有 9 个非空白符的字符串 %2d : 2 位的整数(数位 5 和 6 ) %f :浮点值(数位 7 、 8 、 9) %*d :不存储于任何位置的整数 ' ' :所有连续空白符 %3[0-9] :至多有 3 个十进制数字的字符串(数位 5 和 6 ) %2lc :二个宽字符,使用多字节到宽转换 */ int ret = sscanf(input, "%d%f%9s%2d%f%*d %3[0-9]%2lc", &i, &x, str1, &j, &y, str2, warr); printf("Converted %d fields:\ni = %d\nx = %f\nstr1 = %s\n" "j = %d\ny = %f\nstr2 = %s\n" "warr[0] = U+%x warr[1] = U+%x\n", ret, i, x, str1, j, y, str2, warr[0], warr[1]); #ifdef __STDC_LIB_EXT1__ int n = sscanf_s(input, "%d%f%s", &i, &x, str1, (rsize_t)sizeof str1); // 写 25 到 i , 5.432 到 x , 9 个字节 "thompson\0" 到 str1 ,和 3 到 n 。 #endif }
输出:
Converted 7 fields: i = 25 x = 5.432000 str1 = Thompson j = 56 y = 789.000000 str2 = 56 warr[0] = U+df warr[1] = U+6c34
引用
- C11 标准(ISO/IEC 9899:2011):
- 7.21.6.2 The fscanf function (第 317-324 页)
- 7.21.6.4 The scanf function (第 325 页)
- 7.21.6.7 The sscanf function (第 326 页)
- K.3.5.3.2 The fscanf_s function (第 592-593 页)
- K.3.5.3.4 The scanf_s function (第 594 页)
- K.3.5.3.7 The sscanf_s function (第 596 页)
- C99 标准(ISO/IEC 9899:1999):
- 7.19.6.2 The fscanf function (第 282-289 页)
- 7.19.6.4 The scanf function (第 290 页)
- 7.19.6.7 The sscanf function (第 291 页)
- C89/C90 标准(ISO/IEC 9899:1990):
- 4.9.6.2 The fscanf function
- 4.9.6.4 The scanf function
- 4.9.6.6 The sscanf function
参阅
(C99)(C99)(C99)(C11)(C11)(C11) |
从 stdin 、文件流或缓冲区读取格式化输入 使用可变参数列表 (函数) |
从文件流获取一个字符串 (函数) | |
(C99)(C11)(C11)(C11)(C11) |
打印格式化输出到 stdout 、文件流或缓冲区 (函数) |