twaites@sicom.UUCP (Greg Twaites) (05/29/87)
Here is the C code that allows you to read a DBASE-III file. I verified that it works under Microsoft C v4.0. Hope it does every thing you need. I am not sure where it came from, so hopefully I am not violating anyones copyrights :-). Have fun. Greg Twaites SICOM Inc. !ihnp4!sun!sunburn!sicom!twaites -------------------------------------------------------------------------- /* * These functions are used to read dbase files. * * These functions are provided by Valour Software as a gift. * * The program is for test purposes only. No warranty is expressed nor * implied. USE AT YOUR OWN RISK! * * */ #include <fcntl.h> #include <sys\types.h> #include <sys\stat.h> #include <io.h> #include <malloc.h> typedef struct dbase_head { unsigned char version; /*03 for dbIII and 83 for dbIII w/memo file*/ unsigned char l_update[3]; /*yymmdd for last update*/ unsigned long count; /*number of records in file*/ unsigned int header; /*length of the header *includes the \r at end */ unsigned int lrecl; /*length of a record *includes the delete *byte */ unsigned char reserv[20]; } DBASE_HEAD; typedef struct dbase_fld { char name[11]; /*field name*/ char type; /*field type*/ #define DB_FLD_CHAR 'C' #define DB_FLD_NUM 'N' #define DB_FLD_LOGIC 'L' #define DB_FLD_MEMO 'M' #define DB_FLD_DATE 'D' /* A-T uses large data model but drop it for now */ char far *data_ptr; /*pointer into buffer*/ unsigned char length; /*field length*/ unsigned char dec_point; /*field decimal point*/ unsigned char fill[14]; } DBASE_FIELD; typedef struct fld_list { struct fld_list *next; DBASE_FIELD *fld; char *data; } FLD_LIST; DBASE_HEAD dbhead={0}; FLD_LIST *db_fld_root=0; char *Buffer; char buf_work[255]; int dbfile; /*------------------------------------------------------------code-------*/ main(argc,argv) int argc; char *argv[]; { if(argc!=2) error("Usage is db_dump filename.dbf"); dbfile=open(argv[1],O_RDONLY); if(dbfile==-1) error("Unable to open file"); db3_read_dic(); db3_print_recs(5); printf("\n\n\t\t\tProcessing complete"); close(dbfile); exit(0); } /****************************************************** db3_read_dic() This function is called with a file name to read to create a record type to support the dbase file ******************************************************/ db3_read_dic() { int fields; DBASE_FIELD *fld; if(dbfile==-1) { printf("open failed"); exit(200); } read(dbfile,&dbhead,sizeof(DBASE_HEAD)); if( !(dbhead.version==3 || dbhead.version==0x83) ) error("\n\aVersion %d not supported",dbhead.version); printf("update year %3d\n",dbhead.l_update[0]); printf("update mon %3d\n",dbhead.l_update[1]); printf("update day %3d\n",dbhead.l_update[2]); printf("number of recs %3d\n",dbhead.count); printf("header length %3d\n",dbhead.header); printf("record length %3d\n",dbhead.lrecl); Buffer=malloc(dbhead.lrecl); fields=(dbhead.header-1)/32-1; printf("\nField Name\tType\tLength\tDecimal Pos\n"); while(fields--) { fld=(DBASE_FIELD *)malloc(sizeof(DBASE_FIELD)); if(!fld) error("\n\aNot enough memory\n"); read(dbfile,fld,sizeof(DBASE_FIELD)); printf("%-10s\t %c\t %3d\t %3d\n",fld->name,fld->type, fld->length,fld->dec_point); stack_field(fld); } read(dbfile,Buffer,1); /*read the silly little \r character*/ return; } /****************************************************** db3_print_recs() Read records and print the data ******************************************************/ db3_print_recs(cnt) int cnt; { int bytes; while(cnt) { bytes=read(dbfile,Buffer,dbhead.lrecl); if(bytes!=dbhead.lrecl) break; if(Buffer[0]!='*') { db3_print(); cnt--; } } return; } /****************************************************** db3_print() Print a single record ******************************************************/ db3_print() { FLD_LIST *list, *temp; temp=db_fld_root; printf("\n"); while(temp) { memcpy(buf_work,temp->data,temp->fld->length); buf_work[temp->fld->length]='\0'; printf("%-10s=%s\n",temp->fld->name,buf_work); temp=temp->next; } return; } /****************************************************** stack_field() Add a field to the linked list of fields ******************************************************/ stack_field(fld) DBASE_FIELD *fld; { FLD_LIST *list, *temp; list=(FLD_LIST *)calloc(1,sizeof(FLD_LIST)); if(!list) error("\n\aNot enough memory\n"); list->fld=fld; if(!db_fld_root) { list->data=Buffer+1; /*skip delete byte*/ db_fld_root=list; return; } temp=db_fld_root; while(temp->next) temp=temp->next; temp->next=list; list->data=temp->data + temp->fld->length; return; } /****************************************************** error() Produce error msg and abort ******************************************************/ error(msg) char *msg; { printf(msg); close(dbfile); exit(255); }