在以前的文章中,我提到了折点文件的存储方式.当时采用的是直接在调用时将字符串封装完毕后,利用折点文件对象进行存储.但是这种方法耦合性太大,因此我对折点文件类进行了改进,用户只需输入一个二维实数数组,即可进行存储,同样地在读取时,也是将数据读置一个二维实数数组中的.
///////////////////////////////////////////////////////////////////////////////////////////////////////
其类定义如下:
#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;
}
//////////////////////////////////////////////////////////////////////////