fscanf
函数 <cstdio>
int fscanf ( FILE * stream, const char * format, ... );
从流读取格式化的数据
从流中读取数据,并根据形参格式将它们存储到附加实参指向的位置中。
附加参数应该指向已经分配的对象,该对象的类型由格式字符串中相应的格式说明符指定。
☲ 参数
stream
指向FILE对象的指针,该对象标识要从中读取数据的输入流。
format
包含一系列字符的C字符串,这些字符控制如何处理从流中提取的字符:
-
空白字符 : 该函数将读取并忽略在下一个非空白字符之前遇到的任何空白字符(空白字符包括空格、
换行符和制表符——参见isspace)。格式字符串中的单个空格将验证从流中提取的任意数量的空格字符(
包括none)。
-
非空白字符,格式说明符(%)除外:任何不是一个空白字符(空格、换行符选项卡)或部分格式说明符
(以%开头字符)会使函数从流读取下一个字符,比较这个非空字符,如果匹配,
它被丢弃,函数继续处理format的下一个字符。如果字符不匹配,函数将失败,
返回流中的后续字符,并且不读取。
-
格式说明符:由百分号(%)开头组成的序列表示格式说明符,用于指定从流中检索并存储到附加参数所指向位置的数据的类型和格式。
fscanf的格式说明符遵循以下原型:
%[*][width][length]specifier
其中,末尾的说明符字符是最重要的部分,因为它定义了要提取哪些字符、它们的解释及其对应参数的类型:
说明符 |
描述 |
特性 |
i, u |
Integer |
任意数目的数字,前面可选有符号(+或-)。 |
d |
十进制整数 |
任何的十进制数(0-9),前面可选有符号(+或-)。 |
o |
八进制整数 |
任何八进制数字(0-7),前面可选有符号(+或-)。 |
x |
十六进制整数 |
任意一个十六进制数字(0-9,a-f, A-F),前面可选有0x或0X,前面可选有一个符号(+或-)。 |
f,e,g |
浮点数 |
一组小数,可选地包含一个小数点,可选地前面有一个符号(+或-),
可选地后面有e或E字符和一个十进制整数(或strtod支持的其他一些序列)。
符合C99的实现也支持前加0x或0X的十六进制浮点格式。
|
a |
c |
字符 |
下一个字符。如果指定了非1的宽度,函数将准确读取width字符,
并将它们存储在作为参数传递的数组的后续位置。在末尾不添加空字符。
|
s |
字符串 |
任意数量的非空白字符,在找到的第一个空白字符处停止。在存储序列的末尾自动添加一个终止空字符。 |
p |
指针地址 |
表示指针的字符序列。使用的特定格式取决于系统和库实现,但它与在fprintf中格式化%p所用的格式相同。 |
[characters] |
Scanset |
在括号中指定的任意数量的字符。
在某些库实现中,不是第一个字符的破折号(-)可能会产生不可移植的行为。
|
[^characters] |
取反的scanset |
括号中没有指定为字符的任意数量的字符。 |
n |
总数 |
没有输入。
到目前为止从流读取的字符数存储在指定位置。
|
% |
%后面跟着另一个%匹配一个单独的%。 |
% |
除n外,任何说明符至少要消耗一个字符。否则匹配失败,扫描到此结束。
格式说明符还可以包含子说明符:星号(*)、宽度和长度(按顺序),它们是可选的,遵循以下规范:
子说明符 |
说明 |
* |
一个可选的开始星号表示数据将从流中读取但被忽略(即它没有存储在参数所指向的位置)。 |
width |
指定当前读取操作中要读取的最大字符数(可选)。 |
length |
hh, h, l, ll, j, z, t, L其中一个(可选)。
这将改变相应参数所指向的存储的预期类型(见下面)。
|
这是一个图表,显示了存储输入的相应参数的类型(包括长度子说明符和不包含长度子说明符):
|
说明符 |
length |
d i |
u o x |
f e g a |
c s [] [^] |
p |
n |
(none) |
int* |
unsigned int* |
float* |
char* |
void** |
int* |
hh |
signed char* |
unsigned char* |
|
|
|
signed char* |
h |
short int* |
unsigned short int* |
|
|
|
short int* |
l |
long int* |
unsigned long int* |
double* |
wchar_t* |
|
long int* |
ll |
long long int* |
unsigned long long int* |
|
|
|
long long int* |
j |
intmax_t* |
uintmax_t* |
|
|
|
intmax_t* |
z |
size_t* |
size_t* |
|
|
|
size_t* |
t |
ptrdiff_t* |
ptrdiff_t* |
|
|
|
ptrdiff_t* |
L |
|
|
long double |
|
|
|
注意:绿色行表示C99引入的说明符和子说明符。
... (additional arguments)
根据格式字符串的不同,函数可能需要一个附加参数序列,每个参数包含一个指针,
该指针指向分配的存储空间,在该存储空间中,对提取出来的字符的解释将以相应的类型存储。
这些参数的数量至少应该与格式说明符存储的值的数量一样多。其他参数被函数忽略。
这些参数应该是指针:为了存储对常规变量的fscanf操作的结果,它的名称应该在引用操作符(&)之前(参见示例)。
☉ 返回值
如果成功,函数将返回成功填充参数列表的项数。
该计数可以匹配预期的项数,或者由于匹配失败、读取错误或文件结束的范围而小于(甚至为零)。
如果发生读取错误或在读取时到达文件结束,则设置正确的指示符(feof或ferror)。
并且,如果任意一种情况发生在成功读取任何数据之前,则返回EOF。
如果在解释宽字符时发生编码错误,该函数将errno设置为EILSEQ。
☣ 示例
/* fscanf example */
#include <stdio.h>
int main ()
{
char str [80];
float f;
FILE * pFile;
pFile = fopen ("myfile.txt","w+");
fprintf (pFile, "%f %s", 3.1416, "PI");
rewind (pFile);
fscanf (pFile, "%f", &f);
fscanf (pFile, "%s", str);
fclose (pFile);
printf ("I have read: %f and %s \n",f,str);
return 0;
}
|
这个示例代码创建了一个名为myfile.txt的文件,
并向其中写入一个浮点数和一个字符串。然后,流被倒退并使用fscanf读取两个值。它最终产生类似于:
I have read: 3.141600 and PI
|
⇄ 兼容性
特定的库实现可能支持附加的说明符和子说明符。
这里列出的是最新的C和c++标准(都是在2011年发布的)所支持的,但是绿色的是在C99中引入的
(自c++ 11以来只对c++实现有要求),并且可能不被符合旧标准的库所支持。
🍄 另请参阅
scanf |
从stdin读取格式化的数据(function ) |
fprintf |
将格式化的数据写入流(function ) |
fread |
从流中读取数据块(function ) |
fgets |
从流获取字符串(function ) |