C语言版的DBF本地数据库文件操作函数

        几个月前,翻出以前的一些1993 - 1995年的C/C++老代码,陆续粘贴到了BLOG上,一来以免不小心遗失(以前很多好代码都丢了),二来可供C/C++爱好者,特别是初学者借鉴参考,本以为就这些了,没料到月头又找出一些更老的代码,都是1991年及以前的,前几天我发上来的《C语言版的磁盘文件分片归并排序函数》就是其中之一。今天准备把1991年用TURBOC 2.0写的DBF本地数据库文件操作函数完整的贴在这里,前几个月发的文章《C++老代码 -- DBF数据文件操作类DBFile》应该是我当时从C向C++过渡时根据这里的C代码改写的。

        其实还有个通用的用B+树建立本地数据索引文件的工具代码,本想在《C语言版的磁盘文件分片归并排序函数》之后贴上来,但是由于目前32位计算机与以前的16位计算机的数据类型长度不一样,而索引文件是分索引节点块写道磁盘文件上的,数据类型长度不同必定引起移植错误(以前没想这么多 ^_^ ),再看到《C语言版的磁盘文件分片归并排序函数》很受朋友们捧场(一天的电击量达到了1000多),错误多了会挨骂的,所以,只能等春节后找几天时间改一下(代码很长很复杂的)后再贴出来。顺便在此感谢大家的捧场,也感谢CSDN编辑把文章挂在了首页,才能让这么多的朋友光临。

       需要说明的是,1991年我正好业余学习计算机语言2年多时间,其中包括学习BASIC、PASCAL及汇编等,所以C语言可能掌握的不大好,更谈不上代码设计,加上我又不懂英语,标识符命名也不规范等,因此有什么不对的地方可以写信给我(maozefa@hotmail.com),也可留言,但是代码在16位机上绝对是可行的,记得我以前经常用的,但是要用到32位机上,和DBF文件有关的几个结构的数据类型要改一下,很简单的,只是把int变为short就行了的(好像就2处地方),我自己没改是因为该代码与2个通用排序函数不一样,目前实用价值不大,就让它保持原样吧!

       下面是代码,没写测试程序:

/*
*********************  DBASE 数据文件操作 C 库文件 ************************
*  文  件  名 : MDBFIO.H                                                  *
*  编  制  人 : 湖北省公安县统计局  毛 泽 发                              *
*  日      期 : 1991.8                                                    *
***************************************************************************
*/
#include 
< stdio.h >

#define  MAXFILES   10
#define  MAXFIELD   128          /*  ...   ... 记录最大字段数  */
#define  MAXNAMES   11           /*  ...   ... 字段名最大长度  */
#define  MAXFIESIZE 254          /*  ...   ... 字符字段最大位数  */
#define  MAXWIDTH   19           /*  ...   ... 数据字段最大位数  */
#define  MAXDEC     15           /*  ...   ... 数据小数最大位数  */
#define  DBFFILE    3            /*  ...   ... 头结构开始标记  */
#define  DBFSTREND  0x000d       /*  ...   ... 头结构结束标记  */
#define  DBFEND     26           /*  ...   ... 文件结束标记  */
#define  DELFLAG    '*'          /*            记录删除标记  */
#define  TOP        0l           /*  首记录标志  */
#define  BOTTOM     -1           /*  末记录标志  */
#define  SPACE      32

/*   内部字段信息结构    */
typedef 
struct  dbfield{
   
char            name[MAXNAMES];    /*   字段名   */
   
char            type;              /*   字段类型   */
   
void        far  * tech;             /*   字段数据地址   */
   unsigned 
char   width, dec;        /*   字段长度及小数位   */
   
char            nul[ 14 ];           /*   保留字节   */
}DBFIELD;

/*   DBF 文件头结构   */
typedef 
struct  dbfstr {
   unsigned 
char   dbf3;                  /*   DBASE 数据文件标记   */
   unsigned 
char   date_n,date_y,date_r;  /*   年月日变量   */
   unsigned 
long   record;                /*   记录数变量     */
   unsigned 
int    ldb,lrd;               /*   头结构.记录长度变量   */
   
char            nul[ 20 ];               /*   头结构保留字节变量   */
}DBFSTR;

/*  DBF 文件把柄结构  */
typedef 
struct  dbfile {
  FILE 
* fdb;             /*   文件指针   */
  DBFSTR stru;          
/*   文件头结构  */
  DBFIELD 
* start;        /*   字段结构首指针   */
  
char  fields;           /*   字段数   */
}DBFILE;


/*   外部字段信息结构    */
struct  dbf{
   
char            name[MAXNAMES];    /*   字段名变量   */
   
char            type;              /*   字段类型变量   */
   unsigned 
char   width,dec;         /*   字段长度及小数位变量   */
};
/*  db_error DBASE 文件操作出错信息:
  0: 无错误; 1: 打开文件过多; 2: 文件未找到; 3: 读文件头失败; 4: 写文件头失败;
  5: 关闭文件失败; 6: 打开文件失败; 7: 移动文件指针出错.
*/
extern  unsigned  char  db_error;

int  db_getfields(DBFSTR str);  /*  计算并返回文件字段数   */
void  undberror( void );   /*  清除 DB_ERROR 错误信息  */
int  db_getstr(DBFILE  * f);  /*  读文件头信息, 成功返回 1,否则 0  */
DBFILE 
* db_use( char   * fname);  /*  打开一个已存在文件,返回指针供读写, 出错返回 NULL  */
/*  根据外部字段结构创建一个 .DBF 文件,成功返回指针供读写,出错返回 NULL  */
DBFILE 
* db_create( char   * fname,  struct  dbf  * fd);
/*  关闭一个文件,FLAG = 0,不更新文件头,否则更新;成功返回 1,否则 0  */
int  db_close(DBFILE  * f,  int  flag);
/*  写文件头信息,FLAG = 0 不写字段信息,成功返回 1,否则 0  */
int  db_writestr(DBFILE  * f,  int  flag);
long  db_cpyrec(DBFILE  * fo, DBFILE  * fi,  long  fosta,  long  fista,  long  n, int   * fields);
long  db_fappend(DBFILE  * fo, DBFILE  * fi,  long  starec,  long  n,  int   * fields);
int  db_copy( char   * tofname,  char   * ffname,  int  flag,  long  starec,  long  n, int   * fields);
long  db_goto(DBFILE  * f,  long  record);
long  db_getrecnum(DBFILE  * f);
long  db_skip(DBFILE  * f,  long  n);
int  db_delete(DBFILE  * f,  long  recs);
int  db_recall(DBFILE  * f,  long  recs);
int  db_pack( char   * fname);
/* ** DBFIO.H END ** */

 

/*
*********************  DBASE 数据文件操作 C 库文件 ************************
*  文  件  名 : DB_CLOSE.C                                                *
*  编制人日期 : 湖北省公安县统计局  毛 泽 发 (1991.8)                     *
***************************************************************************
*/
#include 
< dos.h >
#include 
< stdlib.h >
#include 
" dbfio.h "
#ifdef TURBOC
#include 
< alloc.h >
#else
#include 
< malloc.h >
#endif
/*
*********************  DBASE 数据文件操作 C 库函数  ***********************
*  函 数 名: DB_DATE                                                      *
*  参    数: DAT 数据文件头结构指针                                       *
*  功    能: 读系统当前时间到头结构中                                     *
*  返 回 值:                                                              *
***************************************************************************
*/
void  db_date(DBFSTR  * dat)
{
  
char   * p, q[ 5 ];
  union REGS inr;
  inr.h.ah 
=   0x2a ;
  intdos(
& inr,  & inr);
  p 
=  itoa(inr.x.cx, q,  10 +   2 ;
  dat
-> date_n  =  atoi(p);
  dat
-> date_y  =  inr.h.dh;
  dat
-> date_r  =  inr.h.dl;
}
/*
*********************  DBASE 数据文件操作 C 库函数  ***********************
*  函 数 名: DB_CLOSE                                                     *
*  参    数: f DBASE 数据文件指针                                         *
*  功    能: 关闭一个 DBASE 数据文件                                      *
*  返 回 值: 成功 1,否则 0                                                *
***************************************************************************
*/
int  db_close(DBFILE  * f,  int  flag)
{
  
if ( ! f -> fdb)  return   0 ;   /*  无效文件号  */
  
if (flag){          /*  如已向文件写数据,更新文件头结构  */
    db_date(
& f -> stru);
    
if ( ! db_writestr(f,  0 ))  return   0 ;
  }
  
if (fclose(f -> fdb)  ==  EOF){
    db_error 
=   5 ;
    
return   0 ;
  }
  free(f
-> start);
  f
-> fdb  =  NULL;
  
return   1 ;
}
/*
*********************  DBASE 数据文件操作 C 库函数  ***********************
*  函 数 名: db_writestr                                                  *
*  参    数: f:DBASE 数据文件指针,flag = 0不写字段信息,否则整个文件头信息 *
*  功    能: 写文件头信息到数据文件                                       *
*  返 回 值: 成功 1,否则 0                                                *
***************************************************************************
*/
int  db_writestr(DBFILE  * f,  int  flag)
{
  
int  dbend  =  DBFSTREND;
  
if (fseek(f -> fdb,  0l 0 ))  return   0 ;
  
if ( ! fwrite( & f -> stru,  sizeof (DBFSTR),  1 , f -> fdb))  goto  err;
  
if (flag){
    
if (fwrite(f -> start,  sizeof (DBFIELD), f -> fields, f -> fdb)  !=  f -> fields)
      
goto  err;
    
if ( ! fwrite( & dbend,  sizeof ( int ),  1 , f -> fdb))  goto  err;
  }
  
return   1 ;
err:
  db_error 
=   4 ;
}
/* ** DB_CLOSE.C END ** */

 

/*
*********************  DBASE 数据文件操作 C 库文件 ************************
*  文  件  名 : DB_COPY.C                                                 *
*  编制人日期 : 湖北省公安县统计局  毛 泽 发 (1991.8)                     *
***************************************************************************
*/
#include 
" dbfio.h "
#ifdef TURBOC
#include 
< alloc.h >
#else
#include 
< malloc.h >
#endif
#include 
< string .h >
/*
*********************  DBASE 数据文件操作 C 库函数  ***********************
*  函 数 名: DB_COPY                                                      *
*  参    数: tofname:复制文件名;ffname:被复制文件名;flag:0 只复制结构,1 包*
*            括记录;starec:起始记录(0-N); n:记录数;如 n = 0,start及以下全 *
*            部记录;fileds:字段序号表,以 -1 结尾,如fields = 0 复制全部字段*
*  功    能: 按条件复制一个文件内容到另一文件中                           *
*  返 回 值: 成功 0,被复制文件不存在 -1, 复制失败 -2                      *
***************************************************************************
*/
int  db_copy( char   * tofname,  char   * ffname,  int  flag,  long  starec,  long  n,
            
int   * fields)
{
  DBFILE 
* fi,  * fo,  * db_findfile();
  register 
int  i  =   0 , j;
  
if ((fo  =  db_findfile())  ==  NULL)  return   - 2 ;
  
if ((fo -> fdb  =  fopen(tofname,  " w+b " ))  ==  NULL){
    db_error 
=   6 ;
    
return   - 2 ;
  }
  
if ((fi  =  db_use(ffname))  ==  NULL)  return   - 1 ;
  memcpy((
char   * ) & fo -> stru, ( char   * ) & fi -> stru,  sizeof (DBFSTR));
  
if ( ! fields){
    fo
-> start  =  fi -> start;
    fo
-> fields  =  fi -> fields;
  }
  
else {
    
for (; fields[i]  >=   0   &&  fields[i]  <  fi -> fields  &&  i  <  MAXFIELD; i  ++ );
    j 
=   sizeof (DBFIELD)  *  i;
    
if ((fo -> start  =  (DBFIELD  * )malloc(j))  ==  NULL){
      db_close(fi, 
0 );
      fclose(fo
-> fdb);
      fo
-> fdb  =  NULL;
      
return   - 2 ;
    }
    memset(fo
-> start,  0 , j);
    fo
-> fields  =  i;
    fo
-> stru.lrd  =   0 ;
    
for (i  =   0 ; i  <  fo -> fields; i  ++ ){
      j 
=  fields[i];
      memcpy((
char   * ) & fo -> start[i], ( char   * ) & fi -> start[j],  sizeof (DBFIELD));
      fo
-> stru.lrd  +=  fo -> start[i].width;
    }
    fo
-> stru.lrd  +=   1 ;
    fo
-> stru.ldb  =  i  *   32   +   34 ;
  }
  
if (flag) db_cpyrec(fo, fi,  0l , starec, n, fields);
  db_close(fi, 
0 );
  i 
=  db_writestr(fo,  1 );
  
if (fields) free(fo -> start);
  fclose(fo
-> fdb);
  fo
-> fdb  =  NULL;
  
if ( ! i){
    remove(tofname);
    
return   - 2 ;
  }
}
/* ** DB_COPY.C END ** */
/*
*********************  DBASE 数据文件操作 C 库文件 ************************
*  文  件  名 : DB_CPYRE.C                                                *
*  编制人日期 : 湖北省公安县统计局  毛 泽 发 (1991.8)                     *
***************************************************************************
*/
#include 
" dbfio.h "
#ifdef TURBOC
#include 
< alloc.h >
#else
#include 
< malloc.h >
#endif
/*
*********************  DBASE 数据文件操作 C 库函数  ***********************
*  函 数 名: DB_CPYREC                                                    *
*  参    数: fo,fi:分别为复制.被复制文件指针;fosta,fista:分别为fo,fi所指文*
*            件起始记录;n:记录数,n = 0,包括 fista 在内以下全部记录;fields;*
*            字段序号表,为 NULL 复制全部字段                              *
*  功    能: 复制 fi 文件的记录到 fo 文件,如 fo 与 fi 或者 fields 字段数. *
*            对应字段类型.长度及小数不匹配,数据库会出错                   *
*  返 回 值: fo 文件实际记录数(注:必须调用 DB_CLOSE 关库后,文件记录才更新)*
***************************************************************************
*/
long  db_cpyrec(DBFILE  * fo, DBFILE  * fi,  long  fosta,  long  fista,  long  n,
               
int   * fields)
{
  register unsigned 
long  i;
  unsigned 
long  p, q;
  register 
int  j, k;
  
char   * buf;
  
if ((buf  =  ( char   * )malloc(fi -> stru.lrd))  ==  NULL)  return   0l ;
  
if (db_goto(fo, fosta)  ==   - 1l   ||  db_goto(fi, fista)  ==   - 1l return   0l ;
  
if ( ! n) n  =  fi -> stru.record  -  fista;
  
if ( ! fields){
    
for (i  =   0l ; i  <  n; i  ++ ){
      
if ( ! fread(buf, fi -> stru.lrd,  1 , fi -> fdb))  break ;
      
if ( * buf  ==  DELFLAG){
    i 
-- ; n  -- ;
    
continue ;
      }
      
if ( ! fwrite(buf, fo -> stru.lrd,  1 , fo -> fdb))  break ;
    }
  }
  
else {
    
char   * s,  * p;
    
int  m, h;
    
if ((s  =  ( char   * )malloc(fo -> stru.lrd))  ==  NULL)  return   0l ;
    
for (i  =   0l ; i  <  n; i  ++ ){
      p 
=  s;
      
if ( ! fread(buf, fi -> stru.lrd,  1 , fi -> fdb))  break ;
      
if ( * buf  ==  DELFLAG){
    i 
-- ; n  -- ;
    
continue ;
      }
      
* ++   =   * buf;
      
for (m  =   0 ; fields[m]  >=   0 ; m  ++ ){
        
for (k  =   0 , j  =   1 ; k  <  fields[m]; j  +=  fi -> start[k].width, k  ++ );
        
for (h  =  k, k  =  j, j  +=  fi -> start[h].width; k  <  j; k  ++ * ++   =  buf[k];
      }
      
if ( ! fwrite(s, fo -> stru.lrd,  1 , fo -> fdb))  break ;
    }
    free(s);
  }
  free(buf);
  fo
-> stru.record  =  fosta  +  i;
  
return  fo -> stru.record;
}
/*
*********************  DBASE 数据文件操作 C 库函数  ***********************
*  函 数 名: DB_FAPPEND                                                   *
*  参    数: starec:为被追加文件起始记录.其余参数 同 DB_CPYREC.           *
*  功    能: 追加 fi 文件的记录到 fo 文件尾部,其它同 DB_CPYREC            *
*  返 回 值: fo 文件实际记录数,其它同 DB_CPYREC                           *
***************************************************************************
*/
long  db_fappend(DBFILE  * fo, DBFILE  * fi,  long  starec,  long  n,  int   * fields)
{
  
return (db_cpyrec(fo, fi, fo -> stru.record, starec, n, fields));
}
/* ** DB_CPYRE.C END ** */

 

/*
*********************  DBASE 数据文件操作 C 库文件 ************************
*  文  件  名 : DB_CREAT.C                                                *
*  编制人日期 : 湖北省公安县统计局  毛 泽 发 (1991.8)                     *
***************************************************************************
*/
#include 
" dbfio.h "
#ifdef TURBOC
#include 
< alloc.h >
#else
#include 
< malloc.h >
#endif
#include 
< string .h >
/*
*********************  DBASE 数据文件操作 C 库函数  ***********************
*  函 数 名: DB_VERIFIELD                                                 *
*  参    数: fd:外部字段结构数组首指针,末尾字段名首字符应为 ""            *
*  功    能: 检验并校正字段类型.长度和小数位                              *
*  返 回 值: 字段数                                                       *
***************************************************************************
*/
int  db_verifield( struct  dbf  * fd)
{
  register 
int  i, j;
  
for (i  =   0 ; fd[i].name[ 0 &&  i  <  MAXFIELD; i  ++ ){
    
if (fd[i].type  >   ' b '   &&  fd[i].type  <   ' o ' ) fd[i].type  -=   32 ;
    
if (fd[i].type  !=   ' N ' ) fd[i].dec  =   0 ;
    
if (fd[i].width  ==   0 ) fd[i].width  =   1 ;
    
switch (fd[i].type){
      
case   ' C ' :
    
if (fd[i].width  >  MAXFIESIZE) fd[i].width  =  MAXFIESIZE;
        
break ;
      
case   ' N ' :
    
if (fd[i].dec  >  MAXDEC) fd[i].dec  =  MAXDEC;
    
if (fd[i].width  >  MAXWIDTH) fd[i].dec  =  MAXWIDTH;
        
if ((fd[i].width  -  fd[i].dec)  <   2 ) fd[i].width  =  fd[i].dec  +   2 ;
        
break ;
      
case   ' L ' :
        fd[i].width 
=   1 break ;
      
case   ' D ' :
        fd[i].width 
=   8 break ;
      
case   ' M ' :
        fd[i].width 
=   10 break ;
      
default :
        
if (fd[i].name[ 0 ]){
          fd[i].type 
=   ' C ' ; i  -=   2 ;
        }
    }
  }
  
return  i;
}
/*
*********************  DBASE 数据文件操作 C 库函数  ***********************
*  函 数 名: db_create                                                    *
*  参    数: fname:文件名; fd:同上                                        *
*  功    能: 以写/读方式创建一个 DBASE 数据文件                           *
*  返 回 值: 成功 DBFILE 指针, 出错 NULL                                  *
***************************************************************************
*/
DBFILE 
* db_create( char   * fname,  struct  dbf  * fd)
{
  DBFILE 
* f,  * db_findfile();
  register 
int  n, i  =   0 ;
  
if ((f  =  db_findfile())  ==  NULL)  return  NULL;
  
if ((f -> fields  =  db_verifield(fd))  ==  NULL)  return  NULL;
  n 
=   sizeof (DBFIELD)  *  f -> fields;
  
if ((f -> start  =  (DBFIELD  * )malloc(n))  ==  NULL)  return  NULL;
  memset(f
-> start,  0 , n);
  
if ((f -> fdb  =  fopen(fname,  " w+b " ))  ==  NULL){
    free(f
-> start);
    db_error 
=   6 ;
    
return  NULL;
  }
/*  将定义的外部字段信息拷贝到内部字段结构中  */
  
for (n  =   0 ; i  <  f -> fields; i  ++ ){
    strcpy(f
-> start[i].name, fd[i].name);
    f
-> start[i].type  =  fd[i].type;
    f
-> start[i].width  =  fd[i].width;
    f
-> start[i].dec  =  fd[i].dec;
    n 
+=  fd[i].width;
  }
/*  初始化文件头结构  */
  f
-> stru.dbf3  =  DBFFILE;
  f
-> stru.record  =   0l ;
  f
-> stru.ldb  =  f -> fields  *   32   +   34 ;
  f
-> stru.lrd  =  n  +   1 ;
  memset(f
-> stru.nul,  0 20 );
  db_date(
& f -> stru);
  
if ( ! db_writestr(f,  1 )){
    db_close(f, 
0 );
    remove(fname);
    
return  NULL;
  }
  
return  f;
}
/* ** DB_CREAT.C END ** */

 

/*
*********************  DBASE 数据文件操作 C 库文件 ************************
*  文  件  名 : DB_DEL.C                                                  *
*  编制人日期 : 湖北省公安县统计局  毛 泽 发 (1991.8)                     *
***************************************************************************
*/
#include 
" dbfio.h "
/*
*********************  DBASE 数据文件操作 C 库函数  ***********************
*  函 数 名: DB_DELETE                                                    *
*  参    数: f:DBASE 数据文件指针;recs:记录号                             *
*  功    能: 给记录打上删除标记                                           *
*  返 回 值: 成功 DELFLAG, 出错 EOF                                       *
***************************************************************************
*/
int  db_delete(DBFILE  * f,  long  recs)
{
  
if (db_goto(f, recs)  ==   - 1 return  EOF;
  
return (fputc(DELFLAG, f -> fdb));
}
/*
*********************  DBASE 数据文件操作 C 库函数  ***********************
*  函 数 名: DB_RECALL                                                    *
*  参    数: 同 DB_DELETE                                                 *
*  功    能: 恢复打上删除标记的记录                                       *
*  返 回 值: 成功 SPACE, 出错 EOF                                         *
***************************************************************************
*/
int  db_recall(DBFILE  * f,  long  recs)
{
  
if (db_goto(f, recs)  ==   - 1 return  EOF;
  
return (fputc( 32 , f -> fdb));
}
/*
*********************  DBASE 数据文件操作 C 库函数  ***********************
*  函 数 名: DB_PACK                                                      *
*  参    数: fname:DBASE 数据文件名                                       *
*  功    能: 重新组合数据库,以去掉带删除标记的记录                        *
*  返 回 值: 成功 0 ,出错非零                                             *
***************************************************************************
*/
int  db_pack( char   * fname)
{
  
if (db_copy( " $$$$$$$$.$$$ " , fname,  1 0l 0l , NULL))  return   - 1 ;
  
if (remove(fname)  ==   - 1 return   - 1 ;
  
return (rename( " $$$$$$$$.$$$ " , fname));
}
/* ** DB_DEL.C END ** */

 

/*
*********************  DBASE 数据文件操作 C 库文件 ************************
*  文  件  名 : DB_SEEK.C                                                 *
*  编制人日期 : 湖北省公安县统计局  毛 泽 发 (1991.8)                     *
***************************************************************************
*/
#include 
" dbfio.h "
/*
*********************  DBASE 数据文件操作 C 库函数  ***********************
*  函 数 名: DB_GOTO                                                      *
*  参    数: f: DBASE 文件指针;record:记录号 = TOP 首记录, = BOTTOM 末记录*
*  功    能: 移动文件指针到指定的记录号                                   *
*  返 回 值: 成功:指针在文件的实际位置(字节数),出错 -1                    *
***************************************************************************
*/
long  db_goto(DBFILE  * f,  long  record)
{
  
if (record  ==  BOTTOM) record  =  f -> stru.record  -   1 ;
  
if (record  <   0   ||  record  >  f -> stru.record) record  =  f -> stru.record;
  record 
=  record  *  f -> stru.lrd  +  f -> stru.ldb;
  
if (fseek(f -> fdb, record,  0 )){
    db_error 
=   7 ;
    
return   - 1l ;
  }
  
return  record;
}
/*
*********************  DBASE 数据文件操作 C 库函数  ***********************
*  函 数 名: DB_GETRECNUM                                                 *
*  参    数: f: DBASE 文件指针                                            *
*  功    能: 返回当前文件指针所在位置的记录号(注:指针不一定指在记录首字节)*
*  返 回 值: 记录号,出错 -n                                               *
***************************************************************************
*/
long  db_getrecnum(DBFILE  * f)
{
  
long  record;
  
if ((record  =  ftell(f -> fdb))  ==   - 1l ){
    db_error 
=   7 ;
    
return   - 1l ;
  }
  record 
=  (record  -  f -> stru.ldb)  /  f -> stru.lrd;
  
return  record;
}
/*
*********************  DBASE 数据文件操作 C 库函数  ***********************
*  函 数 名: DB_SKIP                                                      *
*  参    数: f: DBASE 文件指针; n:记录数                                  *
*  功    能: 文件指针从当前记录处移动 N 个记录位置                        *
*  返 回 值: 同 DB_GOTO                                                   *
***************************************************************************
*/
long  db_skip(DBFILE  * f,  long  n)
{
  
long  record;
  
if ((record  =  db_getrecnum(f))  ==   - 1l return   - 1l ;
  
return (db_goto(f, record  +  n));
}
/* ** DB_SEEK.C END ** */

 

/*
*********************  DBASE 数据文件操作 C 库文件 ************************
*  文  件  名 : DB_USE.C                                                  *
*  编制人日期 : 湖北省公安县统计局  毛 泽 发 (1991.8)                     *
***************************************************************************
*/
#include 
" dbfio.h "
#ifdef TURBOC
#include 
< alloc.h >
#else
#include 
< malloc.h >
#endif
/*
*********************  DBASE 数据文件操作 C 库函数  ***********************
*  函 数 名: db_getstr                                                    *
*  参    数: f 数据文件指针                                               *
*  功    能: 读数据文件头信息                                             *
*  返 回 值: 成功  1,否则 0                                               *
***************************************************************************
*/
int  db_getstr(DBFILE  * f)
{
/*  读文件头结构  */
  
if ( ! fread( & f -> stru,  sizeof (DBFSTR),  1 , f -> fdb)  ||  f -> stru.dbf3  !=  DBFFILE)
    
goto  err;
/*  读字段结构  */
  f
-> fields  =  db_getfields(f -> stru);
  
if ((f -> start  =  (DBFIELD  * )malloc( sizeof (DBFIELD)  *  f -> fields))  ==  NULL)
    
goto  err;
  
if (fread(f -> start,  sizeof (DBFIELD), f -> fields, f -> fdb)  !=  f -> fields){
    free(f
-> start);
    
goto  err;
  }
  
return   1 ;
err:
  db_error 
=   3 ;
}
/*
*********************  DBASE 数据文件操作 C 库函数  ***********************
*  函 数 名: DB_USE                                                       *
*  参    数: 以读/写方式打开一个已存在的数据文件                          *
*  功    能: fname 数据文件名                                             *
*  返 回 值: 成功 DBFILE 文件指针, 出错 NULL                              *
***************************************************************************
*/
DBFILE 
* db_use( char   * fname)
{
  DBFILE 
* f,  * db_findfile();
  
if ((f  =  db_findfile())  ==  NULL)  return  NULL;  /*  数据文件打开数超过 MAXFILES  */
  
if ((f -> fdb  =  fopen(fname,  " r+b " ))  ==  NULL){
    db_error 
=   2 ;
    
return  NULL;  /*  文件不存在  */
  }
  
if ( ! db_getstr(f)){
    fclose(f
-> fdb);
    f
-> fdb  =  NULL;
    
return  NULL;   /*  非 DBASE 数据文件或读文件头信息有错  */
  }
  
return  f;  /*  返回文件指针  */
}
/* ** DB_USE.C END ** */

Ok,欢迎大家光临!

 

    更新(2008.8.6):果然贴漏了一个文件,现补齐在下面:

  1. /*
  2. *********************  DBASE 数据文件操作 C 库文件 ************************
  3. *  文  件  名 : DB_INIT.C                                                 *
  4. *  编制人日期 : 湖北省公安县统计局  毛 泽 发 (1991.8)                     *
  5. ***************************************************************************
  6. */
  7. #include "dbfio.h"
  8. static DBFILE db_str[MAXFILES]; /*  DBASE 数据文件指针数组 */
  9. static char inits = 0;
  10. unsigned char db_error = 0;
  11. /*
  12. *********************  DBASE 数据文件操作 C 库函数  ***********************
  13. *  函 数 名: initdbfstr                                                   *
  14. *  参    数:                                                              *
  15. *  功    能: 初始化 DBASE 数据文件指针数组 db_str[]                       *
  16. *  返 回 值:                                                              *
  17. ***************************************************************************
  18. */
  19. void initdbfstr(void)
  20. {
  21.   register int i;
  22.   undberror();
  23.   for(i = 0; i < MAXFILES; i ++)
  24.     db_str[i].fdb = NULL; /*  文件指针初始化为 NULL  */
  25.   inits = 1;
  26. }
  27. /*
  28. *********************  DBASE 数据文件操作 C 库函数  ***********************
  29. *  函 数 名: db_findfile                                                  *
  30. *  参    数:                                                              *
  31. *  功    能: 在 db_str[] 中查找未使用的文件指针                           *
  32. *  返 回 值: 成功 DBFILE 指针, 否则 NULL                                  *
  33. ***************************************************************************
  34. */
  35. DBFILE *db_findfile(void)
  36. {
  37.   register int i;
  38.   if(!inits) initdbfstr();   /* 初始化 DBASE 数据文件指针数组 */
  39.   for(i = MAXFILES - 1; i >= 0 && db_str[i].fdb; i --);
  40.   if(i == -1){
  41.     db_error = 1;
  42.     return NULL;
  43.   }
  44.   return(&db_str[i]);
  45. }
  46. /*
  47. *********************  DBASE 数据文件操作 C 库函数  ***********************
  48. *  函 数 名: db_getfields                                                 *
  49. *  参    数: str 文件头结构变量                                           *
  50. *  功    能: 计算数据文件字段数                                           *
  51. *  返 回 值: 数据文件字段数                                               *
  52. ***************************************************************************
  53. */
  54. int db_getfields(DBFSTR str)  /* 计算并返回文件字段数 */
  55. {
  56.   return((str.ldb - 34) / 32);  /*  (文件头结构长 - 34) / 32  */
  57. }
  58. void undberror(void)
  59. {
  60.   db_error = 0;
  61. }
  62. /*** DB_INIT.C END ***/

 

  • 1
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 16
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 16
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值