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>
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地址中去。
Figure1:ffReadFile.dat文件
拥有3个数字行的最后一个数字决定拥有两个数字的行数。用fscanf()函数读取其内的内容以笔记到fscanf()函数的用法。
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); }此时,可以正确的打印第一行内容到屏幕之上。fscanf()函数读取第一行三个数据的过程如下:
Figure2:fscanf()函数读取数据过程
文件指针最开始指向ffReadFile.dat的第一个字符(即1)处,然后fscanf()根据“format”中的第一个“转换符”读取文件中的内容直到不符合当前“转换符”能够转换的字符为止,如果不符合“转换符”的数据为空格或者tab则舍掉空格或者tab使文件指针指向下一个数据。然后fscanf()继续在文件中匹配下一个“转换符”的数据。直到为所有的“转换符”匹配完数据为止。
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; }re的值将是1,从而输出读取成功的oLine.p的值。对于此时的情况,只为&oLine.p成功获取了数据,另外两个地址的数据都获取失败。
re = fscanf(pF, "%d%*3c%d%d", &oLine.p, &oLine.l, &oLine.x);
那么程序的输出结果为:100 3 2
%*3c表示跳过3个字符内容。结合2.1程序就得到了如期的输出结果。
Figure4:ffReadFile.dat
那么如果要读取文件中的第一行内容,书写以下语句即可:
fscanf(pF, "%d,%d,%d", &oLine.p, &oLine.l, &oLine.x);以上提到的逗号甚至可以换成’a’这样的字符,但不可以为字符串(Debian Linux 下验证)。
针对上图的文件,可以使用以下语句
fscanf(pF, "%3d,%d,%d", &oLine.p, &oLine.l, &oLine.x);为&oLine.p读取只有3位长的数据,但因为此时文件指针指向10000中最后的那个0使文件中内容与fscanf()“format”不再匹配,后两个地址不能够正确的获取数据。
以上各个小例子已经笔记了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符号有: