|
|
在以前的文章中,我提到了折点文件的存储方式.当时采用的是直接在调用时将字符串封装完毕后,利用折点文件对象进行存储.但是这种方法耦合性太大,因此我对折点文件类进行了改进,用户只需输入一个二维实数数组,即可进行存储,同样地在读取时,也是将数据读置一个二维实数数组中的.
/////////////////////////////////////////////////////////////////////////////////////////////////////// 其类定义如下: #ifndef POINTS_H #define POINTS_H
#define HEAD_LENGTH (sizeof(long)) #define BLOCK_LENGTH 8
#define TRUE 1 #define FALSE 0
#include <stdio.h> #include <stdlib.h> #include <string.h>
/******* Added these 3 lines ***********/ //文件指针基准常量 //0为文件头,1为当前位置,2为文件尾 #define SEEK_CUR 1 #define SEEK_SET 0 #define SEEK_END 2 /******* end of addition ***************/
typedef char Block[];
class PointsFile{ FILE *fp; char *fileName; long number; //存放了多少个点
//---------------------------------------- //读写当前文件中的块数 //因为我的块数是long型,所以此处所有的int型都改为long void fwrite_number(long value) { put_bytes((char *) &value,sizeof(long));} void put_bytes(const char* bytes,long num) { fwrite(bytes,num,1,fp); }
void get_bytes(char* bytes,long num) { fread(bytes,num,1,fp); } long fread_number() { char ca[sizeof(long)]; get_bytes(ca,sizeof(long)); return *((long *)ca); } //---------------------------------------- public: PointsFile(char* fName); ~PointsFile();
//文件交换以实数数组为媒介 bool read_floats(float fa[][2],long pos,int size); int append_block(float fa[][2],int size);
int get_num_of_blocks() { return number; } //---------------------------------------- void seek_block(long bnum) //块号由1开始 { fseek(fp,HEAD_LENGTH+(bnum-1)*BLOCK_LENGTH*2,SEEK_SET); } }; #endif //////////////////////////////////////////////////////////////////////////////////////////////// 类实现如下: #include "Points.h" #include <iostream.h>
PointsFile::PointsFile(char* fName) { fileName=new char[sizeof(fName)+1]; strcpy(fileName,fName); number=0;
//创建文件并写下块数为0 fp=fopen(fileName,"wb+"); if (fp == 0) { cout<<"折点文件创建失败"<<endl; exit(0); } fwrite_number(number);
//将文件指针移至文件头 fseek(fp,0,SEEK_SET); }
PointsFile::~PointsFile() { fclose(fp); }
int PointsFile::append_block(float fa[][2],int size) { char *b=new char[BLOCK_LENGTH*size*2]; char *tmp=new char[BLOCK_LENGTH];
//将实数数组中的数值置入字符串中 memset(b,0,BLOCK_LENGTH*size*2); strcpy(b,""); for(int i=0;i<size;i++) { for(int j=0;j<2;j++) { sprintf(tmp,"%f",fa[i][j]); strcat(b,tmp); } } //-----------------------------------
//将字符串写入文件 fseek(fp,0,SEEK_END); put_bytes(b,BLOCK_LENGTH*size*2); //更新块数... number=number+size; fseek(fp,0,SEEK_SET); fwrite_number(number); fseek(fp,0,SEEK_SET); //------------------------------------ return number; }
bool PointsFile::read_floats(float fa[][2],long pos,int size) { char *b=new char[BLOCK_LENGTH*size*2]; char *tmp=new char[BLOCK_LENGTH];
//依据块号pos读取相应长度内容,写入b中去 if ((pos+size)<=number+1 && pos>0) seek_block(pos); else return FALSE;
get_bytes(b,BLOCK_LENGTH*size*2); for(int i=0;i<size;i++) { for(int j=0;j<2;j++) { for(int k=0;k<BLOCK_LENGTH;k++) tmp[k]=b[(i*2+j)*BLOCK_LENGTH+k]; sscanf(tmp,"%f",&fa[i][j]); } }
return TRUE; } ///////////////////////////////////////////////////////////////////////////////////// 主函数调用如下: #include "Points.h" #include <iostream.h>
int main() { PointsFile *points=new PointsFile("ps.txt"); float fa[10][2]; float rfa[10][2];
for(int i=0;i<10;i++) { for(int j=0;j<2;j++) { fa[i][j]=(float)i/10+(float)j/10; } } points->append_block(fa,10); points->read_floats(rfa,1,10); for(i=0;i<10;i++) { for(int j=0;j<2;j++) { cout<<rfa[i][j]<<" "; } cout<<endl; }
delete points; return 0; } //////////////////////////////////////////////////////////////////////////
|
|