最近写的程序很多涉及文件读取,学习到的相关内容整理如下:
首先我们整理有关C风格的文件读取。
1、文件打开fopen
FILE*fopen(constchar*filename,const char*mode);
第一个参数文件名,第二个参数打开方式
例如:
FILE *fp=fopen("123.txt","r");
关于第二个参数,主要方式有以下几种:
"r":Opens for reading. If the file does not exist or cannot be found, thefopencall fails.
"w":Opens an empty file for writing. If the given file exists, itscontents are destroyed.
"a":Opens for writing at the end of the file (appending) without removingthe EOF marker before writing new data to the file; creates the file first ifit doesn’t exist.
"r+":Opens for both reading and writing. (The file must exist.)
"w+":Opens an empty file for both reading andwriting. If the given file exists, its contents are destroyed.
"a+":Opens for reading and appending; the appending operation includes theremoval of the EOF marker before new data is written to the file and the EOFmarker is restored after writing is complete; creates the file first if itdoesn’t exist.
以上打开方式均可与"b"组合,表示以二进制的方式打开文件。
2、读取数据 fscanf
待读取的数据如下:
573495.3524 3504188.556
573495.3433 3504188.613
……
intfscanf(FILE*stream,const char*format[,argument ]... );
第一个参数为FILE *指针,第二个参数为格式化读取方式,第三…参数为存储数据的变量
(fscanf遇到空格和换行时结束,注意空格时也结束。这与fgets有区别,fgets遇到空格不结束。)
对于以上数据我们的读取方式为:
fscanf(fp,"%lf %lf",&i,&j);
如果待读取的数据记录比较复杂(两个数据项之间有多个分隔符),例如:
1780, 116938.000000, -1.998542, 0.191398, 2.748348, 0.945257, -1.262179, 9.973212
……
我们可以先写成如下形式:
fscanf(fp,"1780, 116938.000000, -1.998542, 0.191398, 2.748348, 0.945257, -1.262179, 9.973212",……)
然后再将其数字部分替换为%lf即可。
3、判断是否到达文件尾feof()
eg:
while(!feof(fp)){
fscanf(fp,"%lf %lf",&i,&j);
PT*point=new PT();
point->pointX=i;
point->pointY=j;
data.push_back(point);
//cout<<"第"<<++dataNum<<"项数据"<<endl;
}
注:经时间测试发现简单cout语句大约会花费1ms的系统时间,因此cout语句仅限才测试的时候使用。
此外,用fprintf和fscanf函数对磁盘文件操作,由于在输入时要将ASCII码转换为二进制形式,在输出时又要将二进制转换为字符,花费时间比较多。因此,在内存与磁盘频繁交换数据的情况下,最好不用fprintf和fscanf函数。
那么要经常性的访问文件中的数据怎样处理呢?
下面给出一种可行的解决方案:
//以二进制形式打开数据文件
FILE *pFIle=fopen(fileName,"rb");
fseek(pFIle,0,SEEK_END);
//获得文件长度
lSize=ftell(pFIle);
//将文件指针重置到起始
rewind(pFIle);
int charLength=sizeof(char);
//new一个数据存储区域
buffer=new char[sizeof(char)*lSize];
//使用fread(),从pFIle中快速读取数据到buffer
result=fread(buffer,1,lSize,pFIle);
int dataNum=0;
while(dataNum!=(lSize/16)){
PT *point=new PT();
//利用mempy的方式将buffer中的数据"复制"给结构体
memcpy(point,buffer+dataNum*16,16);
data.push_back(point);
++dataNum;
//cout<<"第"<<++dataNum<<"项数据"<<endl;
}
fclose(pFIle);
free(buffer);
方法的前提是,你要了解二进制文件的定义方式,保证memcpy()时可以字节对齐。