📄 dbf.c
字号:
/*
********************* 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;
}
*p ++ = *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 ++) *p ++ = buf[k];
}
if(!fwrite(s, fo->stru.lrd, 1, fo->fdb)) break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -