Ej namieszaliście chłopakowi. Po co w ogole w pliku zapisywać ilośc rekordów, skoro można to sobie obliczyć z jego długości ?
No nic, prosta klasa + demko bazy danych:
#include <stdlib.h>
#include <stdio.h>
#include <io.h>
#include <string.h>
typedef unsigned long ulong;
class f_base{
public:
f_base();
~f_base();
int open(char* file,ulong id); // id - file header
int create(char* file,ulong id,unsigned itemsize);
void close();
void flush();
int get(void* buf,long pos=0,int whence=SEEK_CUR);
int put(void* buf,long pos=0,int whence=SEEK_CUR);
int del(long count,long pos=0,int whence=SEEK_CUR);
int setpos(long newpos,int whence=SEEK_SET);
long getpos();
long getsize();
protected:
unsigned isize;
long curpos;
long items;
FILE* bf;
};
f_base::f_base(){
bf=0;
curpos=0;
isize=0;
items=0;
}
f_base::~f_base(){
close();
}
int f_base::open(char* file,ulong id){
FILE* f=fopen(file,"r+b");
if(!f)return 0;
long fl=filelength(fileno(f));
if(fl<8)goto error;
ulong d;
if(fread(&d,4,1,f)^1)goto error;
if(d^id)goto error;
ulong is; // for 16 & 32 bit compilers compatybility
if(fread(&is,4,1,f)^1)goto error;
items=(fl-8)/is;
isize=unsigned(is); // for 16 & 32 bit compilers compatybility
curpos=0;
bf=f;
return 1;
error:
fclose(f);
return 0;
}
int f_base::create(char* file,ulong id,unsigned itemsize){
FILE* f=fopen(file,"w+b");
if(!f)return 0;
ulong is=itemsize; // for 16 & 32 bit compilers compatybility
if(fwrite(&id,4,1,f)^1)goto error;
if(fwrite(&is,4,1,f)^1)goto error;
isize=itemsize;
curpos=0;
items=0;
bf=f;
return 1;
error:
fclose(f);
return 0;
}
void f_base::close(){
if(bf)fclose(bf);
bf=0;
curpos=0;
isize=0;
items=0;
}
void f_base::flush(){
if(bf)fflush(bf);
}
int f_base::get(void* buf,long pos,int whence){
long p;
switch(whence){
case SEEK_END:p=items+pos;break;
case SEEK_CUR:p=curpos+pos;break;
default :p=pos;
}
if(p<0 || p>items)return 0;
if(fseek(bf,(p*isize)+8,SEEK_SET))return 0;
if(fread(buf,isize,1,bf)^1)return 0;
(curpos=p)++;
return 1;
}
int f_base::put(void* buf,long pos,int whence){
long p;
switch(whence){
case SEEK_END:p=items+pos;break;
case SEEK_CUR:p=curpos+pos;break;
default :p=pos;
}
if(p<0 || p>items)return 0;
if(fseek(bf,(p*isize)+8,SEEK_SET))return 0;
if(fwrite(buf,isize,1,bf)^1)return 0;
(curpos=p)++;
if(curpos>items)items=curpos;
return 1;
}
int f_base::del(long count,long pos,int whence){
long p;
switch(whence){
case SEEK_END:p=items+pos;break;
case SEEK_CUR:p=curpos+pos;break;
default :p=pos;
}
void* b=malloc(isize);
if(!b)return 0;
while(p+count<items){
if(!get(b,p+count,SEEK_SET))goto error;
if(!put(b,p++,SEEK_SET))goto error;
}
free(b);
if(chsize(fileno(bf),(items-count)*isize+8))return 0;
items-=count;
return 1;
error:
free(b);
return 0;
}
int f_base::setpos(long newpos,int whence){
long p;
switch(whence){
case SEEK_END:p=items+newpos;break;
case SEEK_CUR:p=curpos+newpos;break;
default :p=newpos;
}
if(p<0 || p>items)return 0;
if(fseek(bf,(p*isize)+8,SEEK_SET))return 0;
curpos=p;
return 1;
}
long f_base::getpos(){
return curpos;
}
long f_base::getsize(){
return items;
}
struct adr{
char imi[20];
char naz[30];
char tel[20];
} d;
main(){
char* id="adr";
f_base f;
f.create("c:\\adr.dat",*((ulong*)id),sizeof(adr));
printf("\n\nilosc elementow : %ld\n",f.getsize());
printf("pozycja : %ld\n",f.getpos());
strcpy(d.imi,"koziolek");
strcpy(d.naz,"matolek");
strcpy(d.tel,"+48-700-123456");
f.put(&d);
printf("ilosc elementow : %ld\n",f.getsize());
printf("pozycja : %ld\n",f.getpos());
strcpy(d.imi,"czerwony");
strcpy(d.naz,"kapturek");
strcpy(d.tel,"brak");
f.put(&d);
f.flush();
printf("pozycja : %ld\n",f.getpos());
f.close();
f.open("c:\\adr.dat",*((ulong*)id));
printf("ilosc elementow : %ld\n",f.getsize());
printf("pozycja : %ld\n",f.getpos());
f.get(&d);
printf("%s\n%s\n%s\n",d.imi,d.naz,d.tel);
f.del(1,0,SEEK_SET);
printf("ilosc elementow : %ld\n",f.getsize());
printf("pozycja : %ld\n",f.getpos());
f.setpos(0);
f.get(&d);
printf("%s\n%s\n%s\n",d.imi,d.naz,d.tel);
return 0;
}