转载地址:http://blog.csdn.net/misskissc/article/details/25137335
1 原型
int fscanf(FILE *stream, const char* format, …)
功能: 从stream流中连续读取能够匹配format格式的字符到参数列表中对应的变量里。
参数: “stream”是FILE指针类型变量,它指向一个真实的流对象。
“format”是C字符串,由“空格”、“非空格”及“转换符”组成。具体格式为%[*][width][modifiers]type。见2.1与format参数相关的概念。
“…”是与“format”中“转换符”对应变量地址的列表,两地址间用逗号隔开。
返回值:成功时返回从流中读取成功的数据的个数。失败时返回-1(Debian Linux)。
头文件:<stdio.h>
2 使用fscanf()
2.1与format参数相关的概念
fscanf()的format参数允许的格式为:“%[*][width][modifiers]type”。[]中的内容根据需要供选,可缺省,%type必须要有,不可省。
%:是format参数的起始符号,不可缺少。
%[modifiers]type:表一种类型转换符,如%hd表示short int类型转换符。它是format的核心。转换符的作用是将“数据”转换为转换符代表的数据类型,这里提到的数据必须能够转换为转换符代表的数据类型,fscanf读取数据时也只匹配这样的数据。如pF指向一文件,其中只包含数据[123 [空格] 456],用“fscanf(pF, “%d”, &m);”语句是将123这个数据转换为转换符”%d”所代表的数据类型即整型后保存到&m地址中去。
%*[modifiers]type: 表示跳过stream流中能够被转换为[modifiers]type所代表数据类型的数据不读,如在以上的文件中,用“fscanf(pF, “%*d%d”, &m);”就可以跳过对123的读取,而将456转换为整型后保存到&m地址中。%*m[modifiers]type表跳过stream流中能够被转换为[modifiers]type所代表数据类型的m个“字符”不读。如“fscanf(pF,“%*1d%d”, &m);”是将23转换为整型后保存到&m地址中去。
2.2 fscanf()例子
fscanf()可以用于读取文件流中的数据。现设有一个文件内容如下,
Figure1:ffReadFile.dat文件
拥有3个数字行的最后一个数字决定拥有两个数字的行数。用fscanf()函数读取其内的内容以笔记到fscanf()函数的用法。
2.2.1 fscanf()对空格的处理
用fopen成功打开ffReadFile.dat文件后,单用以下语句读取文件的第一行内容:- re = fscanf(pF, "%d%d%d", &oLine.p, &oLine.l, &oLine.x);
- if( 3 == re){
- //Print on stdout
- printf("%d\t%d\t%d\n", oLine.p, oLine.l, oLine.x);
- }
Figure2:fscanf()函数读取数据过程
文件指针最开始指向ffReadFile.dat的第一个字符(即1)处,然后fscanf()根据“format”中的第一个“转换符”读取文件中的内容直到不符合当前“转换符”能够转换的字符为止,如果不符合“转换符”的数据为空格或者tab则舍掉空格或者tab使文件指针指向下一个数据。然后fscanf()继续在文件中匹配下一个“转换符”的数据。直到为所有的“转换符”匹配完数据为止。
2.2.2 fscanf()对不符合“特定格式”数据的处理
当不符合“特定格式”所要求的数据且不为空格和tab时,fscanf()将匹配到符合“特定格式”的数据赋给地址后不再往下读。如现将ffReadFile.dat中的内容修改如下:
Figure3:ffReadFile.dat修改
再用以下代码读取第一行数据,
- re = fscanf(pF, "%d%d%d", &oLine.p, &oLine.l, &oLine.x);
- if( 3 == re){
- //Print on stdout
- printf("%d\t%d\t%d\n", oLine.p, oLine.l, oLine.x);
- }else{
- switch(re){
- case 1:
- printf("oLine.p: %d\n", oLine.p);
- break;
- case 2:
- printf("oLine.p: %d, oLine.l: %d\n", oLine.p, oLine.l);
- break;
- default:
- printf("fscanf() read TypeLine error,re: %d\n", re);
- break;
- }
2.2.3 fscanf()“跳读符:*”
使用‘*’可以跳过文件中的部分内容,比如还是图2中的内容,利用以下的语句替换上个程序的fscanf()语句来读取第一行数据:
- re = fscanf(pF, "%d%*3c%d%d", &oLine.p, &oLine.l, &oLine.x);
那么程序的输出结果为:100 3 2
%*3c表示跳过3个字符内容。结合2.1程序就得到了如期的输出结果。
2.2.4 fscanf()与输入模式相同的读取
如果ffReadFile.dat文件中的内容如下,
Figure4:ffReadFile.dat
那么如果要读取文件中的第一行内容,书写以下语句即可:
- fscanf(pF, "%d,%d,%d", &oLine.p, &oLine.l, &oLine.x);
2.2.5 fscanf()读取指定长度的数据
针对上图的文件,可以使用以下语句
- fscanf(pF, "%3d,%d,%d", &oLine.p, &oLine.l, &oLine.x);
2.2.6 fscanf()的“format”中的[modifiers]type
以上各个小例子已经笔记了fscanf的一些特性,它读数据成功与否是看文件中的数据是否与format的转换符相匹配。type就是C语言中的c(字符转换符), d(整型转换符符), e、E、f、g、 G(浮点型转换符), o(八进制类型转换符), s(字符串类型转换符), u(无符号整型转换符), x、X(16进制数转换符)转换符。个人对转换符的理解是这样的:将内存中的二进制转换为某种类型,如%d是将存储到内存中的一段二进制转换为整型数据。
modifiers是用来为某些数据提供进一步类型转换用的,比如%d表示将匹配到的数据转换为整型。但在C语言的数据类型中还分整型和短整(short int),如果想要将读取到的数据转换为短整型就需要使用modifiers(‘h’)来进一步表示将匹配到的数据转换为短整型。同理,对于其它可以有进一步分类的数据类型也一样,modifiers提供相应的符号来供数据的进一步转换。Modifiers符号有:
- h,加在d, i, n整数类型转换符前面,整体表示short int类型转换符。加在o, u,x整型转换符前,整体表示unsigned short int类型转换符。
- l,加在d, I, n整数类型转换符前,整体表示long int类型转换符。加在o, u, x整型类型转换符前,整体表示unsigned long int类型转换符。加在e, f,g浮点数转换符前,整体表示double类型转换符。
- L,加在e, f, g浮点数类型转换符前,整体表示long double类型转换符。