文件操作方法fscanf

直入主题,首先把经典方法放在前面:

如下情况大量有规律的数据存储在文件中格式化的读取方法:

Almond #EED9C4

Antique Brass #C88A65

Apricot #FDD5B1

Aquamarine #71D9E2

Asparagus #7BA05B

.............................

先上代码:

 1         FILE *fp;          //定义文件指针
 2         char a[20]={0};    //定义两个数组来接受数据
 3         char b[20]={0};
 4
 5         fp=fopen("/Users/My/file","r");  //打开文件
 6         if(fp==NULL)
 7         {
 8             printf("open the file is error!\n");
 9             exit(0);
10         }
11         fseek(fp,0,SEEK_SET);                //获取文件内部指针
12
13
15         while(2==fscanf(fp,"%[^#]%s\n",a,b))    //使用fscanf函数格式化读取文件里的数据,使用#号作为分隔符
16         {
17             printf("a=%s--------\nb=%s\n",a,b);
18            // printf("sizea=%ld\n",sizeof(a));
19            //  NSLog(@"astring=%@",[NSString stringWithFormat:@"%s",a]);
20         }
21
22         fclose(fp);  //关闭文件

读取结果:

a=Shadow,   b=#837050

a=Shamrock,   b=#33CC99

a=Shocking,Pink,   b=#FF6FFF

a=Silver    b=#C9C0BB

a=Sky Blue    b=#76D7EA

a=Spring Green    b=#ECEBBD

a=Sunglow    b=#FFCC33

a=Sunset Orange    b=#FE4C4

解释:

这里使用的C语言提供的一种格式化读取方法,非常像 正则表达式 的读取方式,"%[^#]%s\n"这里的含义就是以#为分隔符读取数据,把数据分为两部分,\n表示读到换行符为止.使用while循环可以读取一个完整的文件直到结束.

所以在最后用a,b可以分别接收到#号前后的数据并存入其中,每次只读取一行.

特别注意:

如果把上边的   %[^#]%s\n  替换为"%[^#]#%s\n"得到的结果如下:

a=Shadow,   b=837050

a=Shamrock,   b=33CC99

a=Shocking,Pink,   b=FF6FFF

a=Silver    b=C9C0BB

a=Sky Blue    b=76D7EA

a=Spring Green    b=ECEBBD

a=Sunglow    b=FFCC33

a=Sunset Orange    b=FE4C40

 再如果替换为 %[^#] %[#^]\n结果会发生如下错误:

a=Shadow,   b=#

a=837050

Shamrock,   b=#

a=33CC99

Shocking,Pink,   b=#

替换为"%[^#]%[#83^]\n"结果如下:

a=Shadow,   b=#83

a=050

Shamrock,   b=#33

a=C99

Shocking,Pink,   b=#

a=F6FFF

Silver    b=#

a=9C0BB

Sky Blue    b=#

a=6D7EA

Spring Green    b=#

(上边这个有点不懂,不仅只按尽可能匹配的截取方式截取,而且文件指针的位置还跳过一个

  b=#83

a=050

) 原来是#837050,但是他的结果把7给跳过了,Why???????????????????????????????????????????????

再次替换为 "%[^#]%[^]\n" 或者%[^#]%[^\n]结果如下:

a=Shadow,   b=#837050

a=

Shamrock,   b=#33CC99

a=

Shocking,Pink,   b=#FF6FFF

a=

Silver    b=#C9C0BB

a=

Sky Blue    b=#76D7EA

a=

Spring Green    b=#ECEBBD

a=

Sunglow    b=#FFCC33

我们发现此时从第二次开始,每次先读取了一个换行符\n,此时可以认为从第一次读取介绍后,文件内部指针每次都以\n为介绍标识,停留在了\n上,所以每次第一个读取的先是换行符\n,所以造成了上述结果.(只是猜测没有具体测试,这几种变化我也不太懂).

后来补充:上面的猜测现在已经证实是正确的了,当把while改为如下:

while(2==fscanf(fp,"%[^#]%[^]\n",a,b))

{

fseek(fp, ftell(fp)+1, SEEK_SET);

printf("a=%s   b=%s\n",a,b);

}

发现结果如下:

a=Shadow,   b=#837050

a=Shamrock,   b=#33CC99

a=Shocking,Pink,   b=#FF6FFF

a=Silver    b=#C9C0BB

a=Sky Blue    b=#76D7EA

总结:  "%[^#]%s\n 和"%[^#]%[^]\n或者%[^#]%[^\n]的区别:

前者%s\n是读取到\n的下一个位置,后者%[^]\n或者%[^#]%[^\n]是读取到\n止.

%[^#]%s\n,  %[^#]#%s\n,   %[^#] %[#XXX^]\n的区别:

%[^#]%s\n:以#号为分割符,前一个读取到#号为止(不包含#号),后一个字符读完到\n的下一个指针位置.

%[^#]#%s\n:  %[^#]是读取到#的前一个位置为止(不包含#), #%s 从#的后一个位置开始读取(不包括#),读取到\n的下一个位置

%[^#] %[#XXX^]\n:  %[#XXX^]尽最大可能的匹配#XXX读取(包含#),最大匹配后读取结束.如" %[#1232^] 遇到 #1525 读出结果为:#1

对上面不太理解??没关系再来个类似的例子,我也加深下学习!

文件中有如下数据:

4,5,41,w,20.585828
4,6,51,r,52.012547

........................

        FILE *fp;
        int fd;
        long dev;
        long offset;
        long length;
        char ch;
        double ts=0.000000;
        fp=fopen("/Users/My/file.save","r");
       if(fp==NULL)
        {
            printf("open the file is error!\n");
            exit(0);
        }
        lseek(fd,0,SEEK_SET);

        //具体解释:fscanf(fp,"%ld,%ld,%ld,%c,%lf\n",&dev,&offset,&length,&ch,&ts)          // 亲,这里的 %ld,%ld,%ld,%c,%lf\n 可不是像下面printf里字符串含义. 这里的逗号(‘,‘)代表的是以逗号(‘,‘)为分          //  隔符(或称为分割单位),以此作为分割数据的依据,因此逗号必不可少,换行符\n则是解析完一行数据的依据.         // 所以说上面的逗号‘,‘和‘\n‘都是必不可少的,否则会造成程序错误,读取失败(多多理解)
         while(5==fscanf(fp,"%ld,%ld,%ld,%c,%lf\n",&dev,&offset,&length,&ch,&ts))          {            // 这里的逗号‘,‘和‘\n‘是来规范输出后的格式,可以省略,但是fscanf中得绝对不可以省略.          printf("%ld,%ld,%ld,%c,%lf\n",dev,offset,length,ch,ts);         }          fclose(fp); 

再举一例: 这个例子很好的说明了fscanf是如何格式化读取文件的

long l;

float fp;

char s[81];

char c;

stream=fopen("/Users/lanou3g/fscanf.out","w+");

if(stream==NULL)

printf("Thefilefscanf.outwasnotopened\n");

else

{

fprintf(stream,"%s,%d,%f,%c","a-string",

65000,3.14159,‘x‘);       // 这个是格式化写入文件,和fscanf是相反的操作,字符串的具体意义和fscanf相似,他们俩配合的相当完美

/*Setpointertobeginningoffile:*/

fseek(stream,0L,SEEK_SET);

/*Readdatabackfromfile:*/

fscanf(stream,"%[^,]",s);   // 注意这里字符串的格式化读取时的格式是%[^,] 说明读取的是字符串且用逗号分割,这个和第一个例子中 %[^#]%s\n的用法很相似, %[^#]%s\n的意思是读取#号分割的前后字符串,第一个字符串必须是格式化的%[^#]以便和后边的字符串做区分,第二个由于后面读到行尾所以可以直接写%s [特别注意的时%s#%s\n的写法和    %[^#]%[^]的写法是错误的,具体原因我也还不太清楚].

fscanf(stream,",%ld",&l);  //下面几个数据都是用",格式符"作为格式化输出标准, "%ld,"这种逗号放后面的写法是错误的.

fscanf(stream,",%f",&fp);

fscanf(stream,",%c",&c);

/*Outputdataread:*/

printf("%s\n",s);

printf("%ld\n",l);

printf("%f\n",fp);

printf("%c\n",c);

fclose(stream);

}

如果把上面的例子中   fscanf(stream,"%[^,]",s);改为fscanf(stream,"%s,",s);读取结果发生错误如下:

a-string,65000,3.141590,x

0

0.000000

文件操作方法fscanf,布布扣,bubuko.com

时间: 2024-08-11 09:56:27

文件操作方法fscanf的相关文章

C#File类常用的文件操作方法(创建、移动、删除、复制等)

File类,是一个静态类,主要是来提供一些函数库用的.静态实用类,提供了很多静态的方法,支持对文件的基本操作,包括创建,拷贝,移动,删除和 打开一个文件. File类方法的参量很多时候都是路径path.File的一些方法可以返回FileStream和StreamWriter的对象.可以 和他们配套使用.System.IO.File类和System.IO.FileInfo类 主要提供有关文件的各种操作,在使用时需要引用System.IO命名空间. 一.File类常用的操作方法 1.创建文件方法 /

C++文件操作方法小结

- 获取文件句柄 - fopen, fclose fopen(filename, opentype): 按照opentype的方式打开指定文件,打开失败返回NULL,否则返回文件句柄. 打开类型的属性(属性可以相互组合): 字符                含义    ──────────────────────────── r(read): 读 w(write):    写 a(append):   追加 t(text): 文本文件,可省略不写 b(banary):  二进制文件 +:  读

python3文件操作方法

在python3中,我们可以使用open打开一个文件,那么打开文件后,文件有什么操作方法呢?接下来我就记录一下比较常用的方法. 1. close() 关闭打开的文件 2. fileno() 返回文件句柄在的索引值,IO多路时会用到 3. flush() 我们使用写相关模式打开文件时,使用write方法写入文件时,如果还没有调用close方法,文件中并没有写入的内容. 这是因为我们写入的东西是保存在内存中的,这样读写速度会快很多. 如果我们想要实时的写入硬盘,我们就可以调用这个方法,将内存中的东西

python学习第二十天文件操作方法

字符有的存储在内存,有的存储在硬盘,文件也有增删改查的操作方法,open()方法,read()方法,readline()方法,close()文件关闭,write()写的方法,seek() 指针移动方法等 1,open() 方法 f=open("www.dc3688.com/huiyuan.txt",mode='r',encoding="utf-8") rr=f.read() print(rr) f.close mode 是指模式 encoding 读取编码方式 2,

C#中File类的文件操作方法详解

File类,是一个静态类,主要是来提供一些函数库用的.静态实用类,提供了很多静态的方法,支持对文件的基本操作,包括创建,拷贝,移动,删除和打开一个文件.File类方法的参量很多时候都是路径path.File的一些方法可以返回FileStream和StreamWriter的对象.可以和他们配套使用. System.IO.File类和System.IO.FileInfo类主要提供有关文件的各种操作,在使用时需要引用System.IO命名空间.下面通过程序实例来介绍其主要属性和方法. (1) 文件打开

asp.net 文件 操作方法

1 /// <summary> 2 /// 移动文件 3 /// </summary> 4 /// <param name="oldPath">源文件路径</param> 5 /// <param name="newPath">目标文件路径</param> 6 /// <param name="fileName">文件名称</param> 7 publ

Asp.Net常用文件操作方法

using System; using System.Collections.Generic; using System.Text; using System.IO; using System.Web; using System.Net; using System.Threading; using EcmaScript.NET; using Yahoo.Yui.Compressor; using System.Xml; using System.Data.OleDb; using System.

[软件]_[Windows]_[产品开发时常用的文件操作方法]

场景: 1. 开发Windows产品时,很多东西都需要自己封装,因为它不像Cocoa那样有很好的对象模型,通过类就可以访问文件相关方法. 比如复制文件夹? 要知道Win32是否提供复制文件夹这个函数还真的通过baidu. MSDN真的很差. 2. 界面开发时打开选择文件夹窗口等. 3. 设置文件创建时间和修改时间等. 4. 也是可以在产品中移植. bas_utility_file.h: #ifndef __BAS_UTILITY_FILE_H #define __BAS_UTILITY_FILE

C#中常用的经典文件操作方法

C#追加文件 StreamWriter sw = File.AppendText(Server.MapPath(".")+"\\myText.txt"); sw.WriteLine("追逐理想"); sw.WriteLine("kzlll"); sw.WriteLine(".NET笔记"); sw.Flush(); sw.Close(); C#拷贝文件 string OrignFile,NewFile; O