|
发表于 2012-2-27 15:55:43
|
显示全部楼层
其实挺好的,sqlite除非在linux系统里面用。
而dbf文件操作,可以在小内存里面跑的很好。
/*描述*/
/* DBASE.C 中包含了:
对XBASE数据库文件(.dbf) 进行常用操作的系列函数。
*/
#include <stdio.h>
#include <dos.h>
#include <bios.h>
#include <malloc.h>
#include <mem.h>
#include <conio.h>
#include <string.h>
#include <fcntl.h>
#include <io.h>
#include <stdlib.h>
#include <ctype.h>
#include "dbase.hpp"
#define SUCCESS 0
#define FALSE -1
#define DOS
#ifdef WINDOWS
static DBF dbfs[30];
static int dbf_used[30]={0};
static char xzfl_name[20];
DBF *Use(char *dbf_name)
{
/*
Inputs: char *dbf_name --- valid xbase file name
Returns: DBF pointer to dbase file if successful
NULL if failure
#Description
The Use() funtion opens a xbase file and returns a
DBF pointer to identify the xbase file. All subsequent
references to the opened xbase file must be using the
pointer until the file is closed. A xbase file can be
opened only once at one time.
*/
DBF *dbf=NULL;
unsigned char byte_buf;
int i,k;
// dbf=(DBF *)malloc(sizeof(DBF));
for(k=0;k<30;k++){
if(dbf_used[k]==0) {
dbf_used[k]=1;
dbf=&dbfs[k];
break;
}
}
if(dbf==NULL){
dbf_used[k]=0;
return NULL;
}
if((dbf->dhHandle=fopen(dbf_name,"rb+"))==NULL)
{
// free(dbf);
dbf_used[k]=0;
return NULL;
}
fread(&byte_buf,1,1,dbf->dhHandle);
if(byte_buf!=0x03&&byte_buf!=0x83) {
fclose(dbf->dhHandle);
// free(dbf);
dbf_used[k]=0;
return NULL;
}
fread(&byte_buf,1,1,dbf->dhHandle);
dbf->dhModifyDate.year=(unsigned char)(byte_buf+1900);
fread(&byte_buf,1,1,dbf->dhHandle);
dbf->dhModifyDate.month=byte_buf;
fread(&byte_buf,1,1,dbf->dhHandle);
dbf->dhModifyDate.day=byte_buf;
fread(&(dbf->dhRecCount),4,1,dbf->dhHandle);
fread(&(dbf->dhStruLen),2,1,dbf->dhHandle);
dbf->dhFieldCount=(dbf->dhStruLen-33)/32;
fread(&(dbf->dhRecLen),2,1,dbf->dhHandle);
dbf->dbf_struct=(DBF_STRUCT *)malloc(dbf->dhFieldCount *sizeof(DBF_STRUCT));
if(dbf->dbf_struct==NULL) {
// free(dbf);
dbf_used[k]=0;
return NULL;
}
fseek(dbf->dhHandle,32L,SEEK_SET);
for(i=0;i<dbf->dhFieldCount;i++)
{
fread(dbf->dbf_struct.dhFieldName,11,1,dbf->dhHandle);
fread(&dbf->dbf_struct.dhFieldType,1,1,dbf->dhHandle);
fread(&dbf->dbf_struct.dhFieldPos,1,1,dbf->dhHandle);
fseek(dbf->dhHandle,3L,SEEK_CUR);
fread(&(dbf->dbf_struct.dhFieldLen),1,1,dbf->dhHandle);
fread(&(dbf->dbf_struct.dhFieldDec),1,1,dbf->dhHandle);
fseek(dbf->dhHandle,14L,SEEK_CUR);
}
fseek(dbf->dhHandle,1L,SEEK_CUR);
dbf->dhCurrRec=(char *)malloc(dbf->dhRecLen+1);
if(dbf->dhCurrRec==NULL) {
free(dbf->dbf_struct);
// free(dbf);
dbf_used[k]=0;
return NULL;
}
if(dbf->dhRecCount>0){
dbf->dhRecNo=-1;
fread(dbf->dhCurrRec,dbf->dhRecLen,1,dbf->dhHandle);
dbf->dhCurrRec[dbf->dhRecLen]=0;
dbf->dhEof=0;
}
else
{ for(i=0;i<dbf->dhRecLen;i++)
dbf->dhCurrRec=' ';
dbf->dhCurrRec[dbf->dhRecLen]=0;
dbf->dhRecNo=0;
dbf->dhEof=1;
}
dbf->dhModify=NO;
return(dbf);
}
int Close(DBF *dbf)
/*
Inputs: DBF *dbf --- DBF pointer to xbase file
Returns: SUCCESS if successful
FALSE if failure
#Description
The Close() function closes a xdbase file
*/
{
int i;
char date_tmp[4];
if(dbf==NULL){
return FALSE;
}
if(dbf->dhModify==YES)
{
fseek(dbf->dhHandle,1L,SEEK_SET);
date_tmp[1]=(char)(dbf->dhModifyDate.year-1900);
date_tmp[2]=dbf->dhModifyDate.month;
date_tmp[3]=dbf->dhModifyDate.day;
fwrite(date_tmp,3,1,dbf->dhHandle);
fwrite(&(dbf->dhRecCount),4,1,dbf->dhHandle);
}
for(i=0;i<10;i++){
if(dbf->dhHandle==dbfs.dhHandle) break;
}
fclose(dbf->dhHandle);
free(dbf->dhCurrRec);
free(dbf->dbf_struct);
// free(dbf);
dbf_used=0;
return SUCCESS;
}
#endif
#ifdef DOS
DBF *Use(char *dbf_name) {
/*
Inputs: char *dbf_name --- valid xbase file name
Returns: DBF pointer to dbase file if successful
NULL if failure
The Use() funtion opens a xbase file and returns a
DBF pointer to identify the xbase file. All subsequent
references to the opened xbase file must be using the
pointer until the file is closed. A xbase file can be
opened only once at one time.
*/
DBF *dbf=NULL;
unsigned char byte_buf;
int i,k;
dbf=(DBF *)malloc(sizeof(DBF));
if(dbf==NULL){
return NULL;
}
if((dbf->dhHandle=fopen(dbf_name,"rb+"))==NULL) {
free(dbf);
return NULL;
}
fread(&byte_buf,1,1,dbf->dhHandle);
if(byte_buf!=0x03&&byte_buf!=0x83) {
fclose(dbf->dhHandle);
free(dbf);
return NULL;
}
fread(&byte_buf,1,1,dbf->dhHandle);
dbf->dhModifyDate.year=(unsigned char)(byte_buf+1900);
fread(&byte_buf,1,1,dbf->dhHandle);
dbf->dhModifyDate.month=byte_buf;
fread(&byte_buf,1,1,dbf->dhHandle);
dbf->dhModifyDate.day=byte_buf;
fread(&(dbf->dhRecCount),4,1,dbf->dhHandle);
fread(&(dbf->dhStruLen),2,1,dbf->dhHandle);
dbf->dhFieldCount=(dbf->dhStruLen-33)/32;
fread(&(dbf->dhRecLen),2,1,dbf->dhHandle);
dbf->dbf_struct=(DBF_STRUCT *)malloc(dbf->dhFieldCount *sizeof(DBF_STRUCT));
if(dbf->dbf_struct==NULL) {
fclose(dbf->dhHandle);
free(dbf); return NULL;
}
fseek(dbf->dhHandle,32L,SEEK_SET);
for(i=0;i<dbf->dhFieldCount;i++)
{
fread(dbf->dbf_struct.dhFieldName,11,1,dbf->dhHandle);
fread(&dbf->dbf_struct.dhFieldType,1,1,dbf->dhHandle);
fread(&dbf->dbf_struct.dhFieldPos,1,1,dbf->dhHandle);
fseek(dbf->dhHandle,3L,SEEK_CUR);
fread(&(dbf->dbf_struct.dhFieldLen),1,1,dbf->dhHandle);
fread(&(dbf->dbf_struct.dhFieldDec),1,1,dbf->dhHandle);
fseek(dbf->dhHandle,14L,SEEK_CUR);
}
fseek(dbf->dhHandle,1L,SEEK_CUR);
dbf->dhCurrRec=(char *)malloc(dbf->dhRecLen+1);
if(dbf->dhCurrRec==NULL) {
fclose(dbf->dhHandle);
free(dbf->dbf_struct);
free(dbf); return NULL;
}
if(dbf->dhRecCount>0){
dbf->dhRecNo=-1;
fread(dbf->dhCurrRec,dbf->dhRecLen,1,dbf->dhHandle);
dbf->dhCurrRec[dbf->dhRecLen]=0;
dbf->dhEof=0;
}
else
{ for(i=0;i<dbf->dhRecLen;i++)
dbf->dhCurrRec=' ';
dbf->dhCurrRec[dbf->dhRecLen]=0;
dbf->dhRecNo=0;
dbf->dhEof=1;
}
dbf->dhModify=NO;
return(dbf);
}
int Close(DBF *dbf)
/*
Inputs: DBF *dbf --- DBF pointer to xbase file
Returns: SUCCESS if successful
FALSE if failure
#Description
The Close() function closes a xdbase file
*/
{
int i;
char date_tmp[4];
if(dbf==NULL){
return FALSE;
}
if(dbf->dhModify==YES)
{
fseek(dbf->dhHandle,1L,SEEK_SET);
date_tmp[1]=(char)(dbf->dhModifyDate.year-1900);
date_tmp[2]=dbf->dhModifyDate.month;
date_tmp[3]=dbf->dhModifyDate.day;
fwrite(date_tmp,3,1,dbf->dhHandle);
fwrite(&(dbf->dhRecCount),4,1,dbf->dhHandle);
}
fclose(dbf->dhHandle);
free(dbf->dhCurrRec);
free(dbf->dbf_struct);
free(dbf);
return SUCCESS;
}
#endif
long Append(DBF *dbf)
/*
Inputs: DBF *dbf --- DBF pointer to xbase file
Returns: current record no.
#Description
The Append() function adds a blank record to the end of xdbase file
*/
{
if(dbf==NULL)
return SUCCESS;
fseek(dbf->dhHandle,0L,SEEK_END);
strset(dbf->dhCurrRec,' ');
dbf->dhCurrRec[dbf->dhRecLen]=0x1a;
fwrite(dbf->dhCurrRec,dbf->dhRecLen+1,1,dbf->dhHandle);
fseek(dbf->dhHandle,-1L,SEEK_END);
dbf->dhCurrRec[dbf->dhRecLen]=0;
dbf->dhModify=YES;
dbf->dhRecNo=++(dbf->dhRecCount);
dbf->dhEof=NO;
return(dbf->dhRecNo);
}
long Write_Record(DBF *dbf,char *newrecn){
/*
Inputs: DBF *dbf --- DBF pointer to xbase file
char *newrecn --- pointer to ASCIIZ string,
which is the content of a record
Returns: current record no.
#Description
The Write_Record() function overwrites a record to the last record of xdbase file
*/
if(dbf==NULL||dbf->dhRecNo==0)
return SUCCESS;
strncpy(dbf->dhCurrRec,newrecn,dbf->dhRecLen);
fseek(dbf->dhHandle,(dbf->dhRecNo-1)*(dbf->dhRecLen)+dbf->dhStruLen,SEEK_SET);
fwrite(dbf->dhCurrRec,dbf->dhRecLen,1,dbf->dhHandle);
return(dbf->dhRecNo);
}
long Go(DBF *dbf,unsigned long step){
/*
Inputs: DBF *dbf --- DBF pointer to xbase file
unsigned long step --- the step form the top of the xbase file
Returns: current record no.
#Description
The Go() function moves the current-record-pointer to the record
whoes record no. is step.
*/
if(dbf==NULL||dbf->dhRecNo==0)
return SUCCESS;
if(step>dbf->dhRecCount){
dbf->dhRecNo=dbf->dhRecCount;
dbf->dhEof=1;
}
else dbf->dhRecNo=step;
fseek(dbf->dhHandle,(dbf->dhRecNo-1)*(dbf->dhRecLen)+dbf->dhStruLen,SEEK_SET);
fread(dbf->dhCurrRec,dbf->dhRecLen,1,dbf->dhHandle);
return(dbf->dhRecNo);
}
char *Read_Record(DBF *dbf,unsigned long step){
/*
Inputs: DBF *dbf --- DBF pointer to xbase file
unsigned long step --- the step form the top of the xbase file
Returns: Pointer to ASCIIZ string which is the content of the read record
#Description
The Read_Record() function reads the record whoes record no. is step
*/
if(step>dbf->dhRecCount)
return("");
else {
Go(dbf,step);
return(dbf->dhCurrRec);
}
}
int Write_In(DBF *dbf,char *buf){
/*
Inputs: DBF *dbf --- DBF pointer to xbase file
char buf --- Pointer to void string which is the content of the written record
Returns: SUCCESS if successful
FALSE if failure
#Description
The Write_In() function writes the record whoes record no. is step
*/
int i,j,str_len=0,rec_bar,buf_bar;
char tmp[100]={0};
char c_value[20]={0};
if(dbf==NULL||dbf->dhRecNo==0)
return SUCCESS;
tmp[0]=buf[0];//del_flag
rec_bar=1; buf_bar=1;
for(i=0;i<dbf->dhFieldCount;i++){
// dbf->dbf_struct.dhFieldType;
// dbf->dbf_struct.dhFieldDec
switch(dbf->dbf_struct.dhFieldType){
case 'C':
for(j=0;j<dbf->dbf_struct.dhFieldLen;j++)
tmp[rec_bar++]=buf[buf_bar++];
if(dbf->dbf_struct.dhFieldLen>1) buf_bar++;
break;
case 'N':
memset(tmp+rec_bar,' ',dbf->dbf_struct.dhFieldLen);
sprintf(c_value,"%d",*(int *)(buf+buf_bar));
strcpy(tmp+rec_bar+dbf->dbf_struct.dhFieldLen\
-strlen(c_value),c_value);
rec_bar+=dbf->dbf_struct.dhFieldLen;
buf_bar+=sizeof(int);
break;
case 'F':
memset(tmp+rec_bar,' ',dbf->dbf_struct.dhFieldLen);
sprintf(c_value,"%.2f",*(float *)(buf+buf_bar));
strcpy(tmp+rec_bar+dbf->dbf_struct.dhFieldLen\
-strlen(c_value),c_value);
rec_bar+=dbf->dbf_struct.dhFieldLen;
buf_bar+=sizeof(float);
break;
case 'L':
if(*(int *)(buf+buf_bar)==1) tmp[rec_bar]='T';
else tmp[rec_bar]='F';
buf_bar++;
rec_bar++;
break;
}
}//end for
for(i=0;i<str_len;i++) if(buf=='\0') buf=' ';
strncpy(dbf->dhCurrRec,tmp,dbf->dhRecLen);
fseek(dbf->dhHandle,(dbf->dhRecNo-1)*(dbf->dhRecLen)+dbf->dhStruLen,SEEK_SET);
fwrite(dbf->dhCurrRec,dbf->dhRecLen,1,dbf->dhHandle);
return SUCCESS;
}
int Read_Out(DBF *dbf,char *buf,unsigned long step){
/*
Inputs: DBF *dbf --- DBF pointer to xbase file
char buf --- Pointer to void string ,to get the record content
Returns: SUCCESS if successful
FALSE if failure
#Description
The Read_Out() function reads the record whoes record no. is step
*/
int i,k,pos_bar=0,rec_bar=0;
float f;
char tmp[30]={0};
if(step>dbf->dhRecCount || step<1L)
return FALSE;
else {
Go(dbf,step);
// return(dbf->dhCurrRec);
buf[pos_bar++]=*(dbf->dhCurrRec+rec_bar++);
for(i=0;i<dbf->dhFieldCount;i++){
// dbf->dbf_struct.dhFieldType;
// dbf->dbf_struct.dhFieldDec
memset(tmp,'\0',20);
switch(dbf->dbf_struct.dhFieldType){
case 'C':
if(dbf->dbf_struct.dhFieldLen==1)
buf[pos_bar++]=*(dbf->dhCurrRec+rec_bar++);
else {
for(k=0;k<dbf->dbf_struct.dhFieldLen;k++)
buf[pos_bar++]=*(dbf->dhCurrRec+rec_bar++);
buf[pos_bar++]='\0';
for(k=0;k<dbf->dbf_struct.dhFieldLen;k++){
// if(buf[pos_bar-2-k]==' ') buf[pos_bar-2-k]='\0'; //modified by lq ,1997\08\09
// else break;
}
}
break;
case 'N':
for(k=0;k<dbf->dbf_struct.dhFieldLen;k++)
tmp[k]=*(dbf->dhCurrRec+rec_bar++);
*(int *)(buf+pos_bar)=atoi(tmp);
pos_bar+=sizeof(int);
break;
case 'F':
for(k=0;k<dbf->dbf_struct.dhFieldLen;k++)
tmp[k]=*(dbf->dhCurrRec+rec_bar++);
for(k=0;;k++) if(tmp[k]!=' ') break;
f=atoi(tmp);
for(k=0;;k++) if(tmp[k]=='.') break;
k++;
f+=(tmp[k++]-'0')*0.1;
f+=(tmp[k]-'0')*0.01;
*(float *)(buf+pos_bar)=f;
pos_bar+=sizeof(float);
break;
case 'L':
tmp[0]=*(dbf->dhCurrRec+rec_bar++);
if(tmp[0]=='F') *(int *)(buf+pos_bar)=0;
else *(int *)(buf+pos_bar)=1;
pos_bar+=1;
break;
default: break;
}//end switch
}
}
return SUCCESS;
}
long Skip(DBF *dbf,int step){
/*
Inputs: DBF *dbf --- DBF pointer to xbase file
int step --- the steps to move from current record.
Returns:the current record no.
#Description
The Skip() function moves the current-record-pointer.
*/
if(dbf==NULL||dbf->dhRecNo==0)
return SUCCESS;
if(dbf->dhRecNo+step<1)
step=1-dbf->dhRecNo;
else if(dbf->dhRecNo+step>dbf->dhRecCount)
{
step=dbf->dhRecCount-dbf->dhRecNo;
dbf->dhEof=1;
}
dbf->dhRecNo+=step;
if(step!=1)
fseek(dbf->dhHandle,dbf->dhRecLen*(step-1),SEEK_CUR);
fread(dbf->dhCurrRec,dbf->dhRecLen,1,dbf->dhHandle);
return(dbf->dhRecNo);
}
/*
int MyCopy(char *source,char *dest){
int readlen=4096;
int readcnt;
char ptr[4100]={0};
FILE *fp1,*fp2;
fp1=fopen(source,"rb");
if(fp1==NULL) return -1;
fp2=fopen(dest,"wb");
if(fp2==NULL) {
fclose(fp1);
return -1;
}
for(;;){
#ifdef MTASk
//... save filepos
tDelay(0);
//... restore filepos
#endif
readcnt=fread(ptr,1,readlen, fp1);
if(readcnt) { fwrite(ptr,1,readcnt,fp2); fflush(fp2);}
if(readcnt!=readlen) break;
}
fclose(fp1); fclose(fp2);
return 0;
}
*/
int MyStrcmp(char *source,char *match){
int i,len;
int retv=0;
len=strlen(match);
for(i=0;i<len;i++){
if(match=='?') continue;
if(source==match) continue;
else { retv=-1;break;}
}
return retv;
}
int Find(DBF *dbf,char *match,int match_pos,long startno,long *recno){
/*
match---match string
match_pos---the start matching position in the record string.
//match_pos=(sun of the previous field lenth)+1
startno---the start recordno in the dbf
recno---the first matched record no in dbf
return --- SUCCESS , FALSE
note: char '?' in match string,indicate that this char is ignored in matching.
*/
int found=0,i,j;
// char record[200]={0};
char *record;
if(Go(dbf,startno)!=startno) return FALSE;
record=new char[dbf->dhRecLen];
if(!record) {
printf("\nError: cannot alloc mem,in Find()");
return FALSE;
}
*recno=startno;
for(i=startno;!eof(dbf);i++){
strcpy(record,Read_Record(dbf,i));
Skip(dbf,1); (*recno)=i;
if(record[0]!=' ') continue;
if(MyStrcmp(record+match_pos,match)==0) found=1;
else found=0;
if(found) break;
}
delete record;
if(found) return SUCCESS;
else return FALSE;
}
--------------
#define recount(dbf) (dbf->dhRecCount)
#define recno(dbf) (dbf->dhRecNo)
#define isdeleted(dbf)(*(dbf->dhCurrRec)=='*')
#define eof(dbf)(dbf->dhEof)
#define field_name(dbf,field_no)((dbf)->dbf_struct[(field_no)-1].dhFieldName)
#define YES 1
#define NO 0
typedef struct {
int dhType;
struct date dbModifyDate;
long dhRecCount;
unsigned dhStruLen;
int DhFieldCount;
int dhRecLen;
char dhReserved[18];
} DBFHEAD;
typedef struct {
int dhHandle;
unsigned dhFileSize;
} DBTHead;
typedef struct {
char dhFieldName[11];
char dhFieldType;
char dhFieldLen;
char dhFieldDec;
int dhFieldPos;
} DBF_STRUCT;
struct dhDate{
unsigned char year;
unsigned char month;
unsigned char day;
};
typedef struct {
FILE *dhHandle;
struct dhDate dhModifyDate;
long dhRecCount;
unsigned int dhStruLen;
int dhFieldCount;
int dhRecLen;
DBF_STRUCT *dbf_struct;
long dhRecNo;
char *dhCurrRec;
int dhEof;
int dhModify;
}DBF;
typedef struct{
int handle;
unsigned long filesize;
}DBT;
/*
typedef struct{
int handle;
long filesize;
long node_position;
long root_position;
int i_p_node;
int text_len;
char *key;
char key_type;
int key_len;
NODE *node;
int node_type;
int i_count;
long per_node;
long suc_node;
NODE *i_front;
NODE *i_rear;
NODE *u_curr;
int update_tag;
}IDX;
*/
int Write_In(DBF *dbf,char *buf);
int Read_Out(DBF *dbf,char *buf,unsigned long step);
long Write_Record(DBF *dbf,char *newrecn);
char *Read_Record(DBF *dbf,unsigned long step);
DBF *Use(char *);
int Create(char *dbf_name,int dhFieldCount,DBF_STRUCT *dbf_stru);
int Close(DBF *dbf);
long Go(DBF *dbf,unsigned long step);
long Delete(DBF *dbf);
long Recall(DBF *dbf);
long Skip(DBF *dbf,int step);
long Append(DBF *dbf);
int CreateDbf(int flag,char *filename);
int MyStrcmp(char *source,char *match);
int Find(DBF *dbf,char *match,int match_pos,long startno,long *recno); |
|