分享
 
 
 

c语言写的*.dbf文件的操作函数库

王朝c/c++·作者佚名  2006-01-10
窄屏简体版  字體: |||超大  

为什么编写本函数库?

目前好多电力方面的抄表器由于其RAM内存及FLASH闪存的空间都比较小,没有办法象java那样调用各种基于各种大型数据库的外界jar包进行数据采集工作。为此,dbf这种简单的结构型数据库成为手选。另外,因为抄表器要求的数据格式也比较简单,选用这种结构型的最贴合实际。

基于以上两点,本人上网搜了些这方面的资料,想down一个.dbf驱动,但水平有限没找着,只好自己编写了。

直接贴代码吧:

1:HT_DBF.H,定义了.dbf的几个数据结构。

/**************************************************************

** c语言操作dbf文件

**

** 目前只支持int--N,char--C

**************************************************************/

#define MAX_INT_LENTH 20

#define MAX_FLOAT_LENTH 20

#define MAX_CHAR_LENTH 254

/***************************************************************

* 数据库表中的列声明,包含一些列属性

***************************************************************/

typedef struct field

{

char FIELD_NAME[11];

char FIELD_TYPE;

int FIELD_X;

int FIELD_Y;

unsigned char FIELD_LENTH;

unsigned char FIELD_FLOAT_LENTH;

int index;

struct field * next;

}DBF_FIELD;

/***************************************************************

* 数据库表的配置信息,包含 文件开始标志,最后更新日期,记录总数,文件头大小,记录大小,列属性链表

* 数据库文件句柄,当前记录

***************************************************************/

typedef struct {

unsigned char BEGIN_FLAG;

unsigned char LAST_UPPDATE_TIME[3];

long RECORD_COUNT;

int HEAD_SIZE;

int RECORD_SIZE;

DBF_FIELD *head;

int DBF_HANDLE;

long current;

}DBF_CONFIG;

/***************************************************************

* 数据表中的一条记录

* 为了通用性,仅用一个 void *指示

* 其中的具体内容,可以参照DBF_CONFIG中的DBF_FIELD *head进行解析

***************************************************************/

typedef struct record

{

void * value;

}DBF_RECORD;

2:HT_DBF.C,操作函数库

#define __ASM asm

#include <stdlib.h>

#include <stdio.h>

#include <conio.h>

#include <io.h>

#include <dos.h>

#include <share.h>

#include <fcntl.h>

#include <string.h>

#include <mem.h>

#include "..\project\ht_dbf.h"

DBF_CONFIG * dbfopen(char *fname,DBF_CONFIG * db_con);

int dbfclose(DBF_CONFIG * con);

int dbfread(DBF_CONFIG * con,DBF_RECORD * record);

int dbfgetFieldByIndex(DBF_CONFIG * con,DBF_RECORD * record,int index,void * return_value);

int dbfgetFieldByName(DBF_CONFIG * con,DBF_RECORD * record,char* name,void * return_value);

int dbfgetFloatByIndex(DBF_CONFIG * con,DBF_RECORD * record,int index,void * return_value);

int dbfgetFloatByName(DBF_CONFIG * con,DBF_RECORD * record,char* name,void * return_value);

int dbfgetCharByIndex(DBF_CONFIG * con,DBF_RECORD * record,int index,void * return_value);

int dbfgetCharByName(DBF_CONFIG * con,DBF_RECORD * record,char* name,void * return_value);

int dbfsetFieldByIndex(DBF_CONFIG * con,DBF_RECORD * record,int index,void * value);

int dbfsetFieldByName(DBF_CONFIG * con,DBF_RECORD * record,char* name,void * value);

int dbfsetFloatByIndex(DBF_CONFIG * con,DBF_RECORD * record,int index,void * value);

int dbfsetFloatByName(DBF_CONFIG * con,DBF_RECORD * record,char* name,void * value);

int dbfsetCharByIndex(DBF_CONFIG * con,DBF_RECORD * record,int index,void * value);

int dbfsetCharByName(DBF_CONFIG * con,DBF_RECORD * record,char* name,void * value);

char *ccstr( char *str);

void dbf_info();

void dbf_info()

{

char column_name[12];

DBF_FIELD *cur=NULL;

DBF_RECORD record;

float b=0.0;

float c;

char *record_value;

char ret_val[MAX_CHAR_LENTH+1];

/*打开数据库*/

DBF_CONFIG *con=dbfopen("..\\project\\CBDATA.DBF",NULL);

/*数据库配置信息*/

printf("BEGIN_FLAG:%d\n",con->BEGIN_FLAG);

printf("LAST_UPPDATE_TIME:%d",con->LAST_UPPDATE_TIME[0]);

printf(" - %d",con->LAST_UPPDATE_TIME[1]);

printf(" - %d\n",con->LAST_UPPDATE_TIME[2]);

printf("RECORD_COUNT:%d\n",con->RECORD_COUNT);

printf("HEAD_SIZE:%d\n",con->HEAD_SIZE);

printf("RECORD_SIZE:%d\n",con->RECORD_SIZE);

printf("DBF_HANDLE:%d\n",con->DBF_HANDLE);

printf("current:%d\n",con->current);

/*列信息*/

cur=con->head;

while(cur!=NULL){

strncpy(column_name,cur->FIELD_NAME,11);

column_name[11]='\0';

printf("FIELD-INFO-->NAME:%s,TYPE:%c,X:%d,Y:%d,LENTH:%d,FLOAT_LENTH:%d,index:%d\n",column_name,

cur->FIELD_TYPE,cur->FIELD_X,cur->FIELD_Y,cur->FIELD_LENTH,cur->FIELD_FLOAT_LENTH,cur->index);

cur=cur->next;

}

/*读取第2条记录*/

con->current=1;

dbfread(con,&record);

record_value=(char *)malloc(con->RECORD_SIZE+1);

memcpy(record_value,record.value,con->RECORD_SIZE);

*(record_value+con->RECORD_SIZE)='\0';

printf(record_value);

printf("\n");

dbfgetFloatByName(con,&record,"cs1",&b);

printf("A:%f\n",b);

dbfgetFloatByIndex(con,&record,2,&c);

printf("c:%f\n",c);

printf("\n");

dbfgetCharByName(con,&record,"HM",ret_val);

memset(ret_val,'\0',sizeof(ret_val));

dbfgetCharByIndex(con,&record,1,ret_val);

printf("ret_val:%s\n",ret_val);

printf("\ncurrent:%d\n",con->current);

/*改写数据库记录*/

con->current=1;

b=41.01;

//dbfsetFieldByIndex(con,&record,7,&b);

dbfsetFloatByIndex(con,&record,7,&b);

sprintf(ret_val,"%-254s","01-001-01");

dbfsetCharByName(con,&record,"bh",ret_val);

sprintf(ret_val,"%-254s","太平路1号");

dbfsetCharByName(con,&record,"dz",ret_val);

/*关闭数据库*/

dbfclose(con);

getch();

}

/**********************************************************************************************************/

/******************************************

* 打开指定文件名的文件,并初始化DBF_CONFIG。

******************************************/

DBF_CONFIG * dbfopen(char *fname,DBF_CONFIG * db_con)

{

unsigned tmp,field_x;

int fhandle;

char fhead[12];

char field_desc[32];

long pos=0;

DBF_FIELD *field=NULL;

DBF_FIELD *cur=NULL;

if(_dos_open(fname, O_RDWR, &fhandle)!=0)

{

printf("不能打开文件:%s\n",fname);

return NULL;

}

db_con = (DBF_CONFIG *)malloc(sizeof(DBF_CONFIG));

_dos_read(fhandle, fhead, 12, &tmp);

/*基本信息*/

db_con->BEGIN_FLAG=(unsigned char)fhead[0];

memcpy(db_con->LAST_UPPDATE_TIME,fhead+1,3);

db_con->RECORD_COUNT=*(long*)&fhead[4];

db_con->HEAD_SIZE=*(unsigned *)&fhead[8];

db_con->RECORD_SIZE=*(unsigned *)&fhead[10];

/*状态信息*/

db_con->DBF_HANDLE=fhandle;

db_con->current=1;

/*数据库表属性列表,Delphi3.0创建的数据库表,没有FIELD_X,FIELD_Y字段,Visial FoxPro中有。*/

/*Delphi3.0的BEGIN_FLAG=03H,Visial FoxPro的BEGIN_FLAG=30H,可据此进行以下的初始化*/

lseek(fhandle, 0L, SEEK_SET);

lseek(fhandle, 32L, SEEK_SET);

pos=1;

field_x=1;

while((++pos*32)<db_con->HEAD_SIZE)

{

_dos_read(fhandle, field_desc, 32, &tmp);

field=(DBF_FIELD *)malloc(sizeof(DBF_FIELD));

memcpy(field->FIELD_NAME,field_desc,11);

field->FIELD_TYPE=field_desc[11];

field->FIELD_LENTH=(unsigned char)field_desc[16];

field->FIELD_FLOAT_LENTH=(unsigned char)field_desc[17];

if(db_con->BEGIN_FLAG==0x30)

{

field->FIELD_X=*(unsigned *)&field_desc[12];

field->FIELD_Y=*(unsigned *)&field_desc[14];

}

else

{

field->FIELD_X=field_x;

field->FIELD_Y=0;

field_x+=(unsigned)field->FIELD_LENTH;

}

field->index=pos-1;

field->next=NULL;

if(pos*32==64)

{

cur=field;

db_con->head=field;

}

else

{

cur->next=field;

cur=field;

}

}

return db_con;

}

/******************************************

* 关闭数据库,并且释放DBF_CONFIG内存。

******************************************/

int dbfclose(DBF_CONFIG * con)

{

DBF_FIELD *cur=NULL;

DBF_FIELD *deleted=NULL;

if(con==NULL) return 0;

/*释放DBF_FIELD所占内存*/

cur=con->head;

while(cur!=NULL)

{

deleted=cur;

cur=deleted->next;

free(deleted);

}

/*关闭文件句柄*/

_dos_close(con->DBF_HANDLE);

/*释放DBF_CONFIG所占内存*/

free(con);

return 0;

}

/******************************************

* 得到DBF_CONFIG中current所指示的记录

******************************************/

int dbfread(DBF_CONFIG * con,DBF_RECORD * record)

{

unsigned tmp;

if(con==NULL)

{

printf("您没有初始化DBF_CONFIG!\n");

return -1;

}

if(record==NULL)

{

record=(DBF_RECORD *)malloc(sizeof(DBF_RECORD));

}

if(record->value==NULL)

{

record->value=(void *)malloc(con->RECORD_SIZE+1);

}

lseek(con->DBF_HANDLE, (long)(con->HEAD_SIZE+(con->RECORD_SIZE+1)*(con->current-1)), SEEK_SET);

_dos_read(con->DBF_HANDLE, record->value, con->RECORD_SIZE+1, &tmp);

if(con->current<con->RECORD_COUNT)

con->current++;

return 0;

}

/******************************************

* 写入DBF_CONFIG中current所指示的记录

******************************************/

int dbfwrite(DBF_CONFIG * con,DBF_RECORD * record)

{

unsigned tmp;

lseek(con->DBF_HANDLE, (long)(con->HEAD_SIZE+(con->RECORD_SIZE+1)*(con->current-1)), SEEK_SET);

_dos_write(con->DBF_HANDLE, record->value, con->RECORD_SIZE+1, &tmp);

return 0;

}

/******************************************

* 读取DBF_RECORD相应的FIELD

* 目前仅支持C-char,N-float,F-float

* return 0:正确

* -1:没有此索引

* -2:没有此列名称

******************************************/

int dbfgetFieldByIndex(DBF_CONFIG * con,DBF_RECORD * record,int index,void * return_value)

{

DBF_FIELD* field=con->head;

char field_type;

float rfloat;

unsigned char * temp;

char float_buf[MAX_FLOAT_LENTH+1];

while(field!=NULL)

{

if(field->index==index)

{

/*根据field的类型进行判断,并生成合适的值返回*/

switch(field->FIELD_TYPE)

{

case 'F':

case 'N':

temp=(unsigned char *)record->value;

memcpy(float_buf,temp+field->FIELD_X,field->FIELD_LENTH);

float_buf[MAX_FLOAT_LENTH]='\0';

printf("float_buf:%0x\n",float_buf);

rfloat=atof(float_buf);

memcpy(return_value,(void *)&rfloat,4);

printf("rfloat:%f\n",rfloat);

break;

case 'C':

default:

if(return_value==NULL)

{

printf("return_value需要预先分配空间!\n");

return -1;

}

temp=(unsigned char *)record->value;

memcpy(return_value,temp+field->FIELD_X,field->FIELD_LENTH);

break;

}

return 0;

}

field=field->next;

}

printf("没有此索引index=%d\n",index);

return -1;

}

int dbfgetFieldByName(DBF_CONFIG * con,DBF_RECORD * record,char* name,void * return_value)

{

DBF_FIELD* field=con->head;

char field_type;

int index=0;

while(field!=NULL)

{

if((field->FIELD_LENTH>0)&&(strncmpi(field->FIELD_NAME,name,strlen(name)<field->FIELD_LENTH?strlen(name):field->FIELD_LENTH)==0))

{

index=field->index;

break;

}

field=field->next;

}

if(index==0)

{

printf("没有此列名称name=%s\n",name);

return -2;

}

return dbfgetFieldByIndex(con,record,index,return_value);

}

/*特殊的针对Float-N,Float-F的读取操作*/

/******************************************

*return 0:正确

* -1:没有此索引

* -2:没有此列名称

* -3:类型不匹配!您试图读取非Float或int型字段

******************************************/

int dbfgetFloatByIndex(DBF_CONFIG * con,DBF_RECORD * record,int index,void * return_value)

{

DBF_FIELD* field=con->head;

char field_type;

while(field!=NULL)

{

if(field->index==index)

{

if(field->FIELD_TYPE=='N'||field->FIELD_TYPE=='F')

return dbfgetFieldByIndex(con,record,index,return_value);

else

{

printf("类型不匹配!您试图用dbfgetFloatByIndex去读取非Float或int型字段\n");

return -3;

}

}

field=field->next;

}

printf("没有此索引index=%d\n",index);

return -1;

}

int dbfgetFloatByName(DBF_CONFIG * con,DBF_RECORD * record,char* name,void * return_value)

{

DBF_FIELD* field=con->head;

char field_type;

int index=0;

while(field!=NULL)

{

if((field->FIELD_LENTH>0)&&(strncmpi(field->FIELD_NAME,name,strlen(name)<field->FIELD_LENTH?strlen(name):field->FIELD_LENTH)==0))

{

if(field->FIELD_TYPE=='N'||field->FIELD_TYPE=='F')

{

index=field->index;

break;

}

else

{

printf("类型不匹配!您试图用dbfgetFloatByName去读取非Float或int型字段\n");

return -3;

}

}

field=field->next;

}

if(index==0)

{

printf("没有此列名称name=%s\n",name);

return -2;

}

return dbfgetFieldByIndex(con,record,index,return_value);

}

/*特殊的针对char-C或其他小于等于"MAX_CHAR_LENTH"个字符的串的读取操作*/

/******************************************

*@return_value:必须在调用此函数前已经声明并分配空间,一般可以定义为unsigned char ret[MAX_CHAR_LENTH+1];

* return 0:正确

* -1:没有此索引

* -2:没有此列名称

******************************************/

int dbfgetCharByIndex(DBF_CONFIG * con,DBF_RECORD * record,int index,void * return_value)

{

return dbfgetFieldByIndex(con,record,index,return_value);

}

int dbfgetCharByName(DBF_CONFIG * con,DBF_RECORD * record,char* name,void * return_value)

{

return dbfgetFieldByName(con,record,name,return_value);

}

/******************************************

* 写入DBF_RECORD相应的FIELD

* 目前仅支持C-char,N-float,F-float

* value 指向一个float或一个char型数组,若为数组则此数组一般为MAX_CHAR_LENTH长

* 但一定要大于等于field->FIELD_LENTH,可在数组末尾补齐空格0x20。

* return 0:正确

* -1:没有此索引

* -2:没有此列名称

******************************************/

int dbfsetFieldByIndex(DBF_CONFIG * con,DBF_RECORD * record,int index,void * value)

{

DBF_FIELD* field=con->head;

char field_type;

unsigned char * temp;

/*以下用于float和int*/

float rfloat;

char f_length[3],f_f_length[3],f_format[10]={"%"};

char float_buf[MAX_FLOAT_LENTH+1];

/*以下用于char*/

unsigned char *temp2;

while(field!=NULL)

{

if(field->index==index)

{

/*根据field的类型进行判断,并生成合适的值返回*/

switch(field->FIELD_TYPE)

{

case 'F':

case 'N':

rfloat=*(float *)value;

itoa(field->FIELD_LENTH,f_length,10);

itoa(field->FIELD_FLOAT_LENTH,f_f_length,10);

strcat(f_format,f_length);

strcat(f_format,".");

strcat(f_format,f_f_length);

strcat(f_format,"f");

sprintf(float_buf,f_format,rfloat);

temp=(unsigned char *)record->value;

memcpy(temp+field->FIELD_X,float_buf,field->FIELD_LENTH);

dbfwrite(con,record);

break;

case 'C':

default:

if(value==NULL)

{

printf("value未设定!\n");

return -1;

}

temp=(unsigned char *)record->value;

temp2=(unsigned char *)value;

memcpy(temp+field->FIELD_X,temp2,field->FIELD_LENTH);

dbfwrite(con,record);

break;

}

return 0;

}

field=field->next;

}

printf("没有此索引index=%d\n",index);

return -1;

}

int dbfsetFieldByName(DBF_CONFIG * con,DBF_RECORD * record,char * name,void * value)

{

DBF_FIELD* field=con->head;

char field_type;

int index=0;

while(field!=NULL)

{

if((field->FIELD_LENTH>0)&&(strncmpi(field->FIELD_NAME,name,strlen(name)<field->FIELD_LENTH?strlen(name):field->FIELD_LENTH)==0))

{

index=field->index;

break;

}

field=field->next;

}

if(index==0)

{

printf("没有此列名称name=%s\n",name);

return -2;

}

return dbfsetFieldByIndex(con,record,index,value);

}

int dbfsetFloatByIndex(DBF_CONFIG * con,DBF_RECORD * record,int index,void * value)

{

DBF_FIELD* field=con->head;

char field_type;

while(field!=NULL)

{

if(field->index==index)

{

if(field->FIELD_TYPE=='N'||field->FIELD_TYPE=='F')

return dbfsetFieldByIndex(con,record,index,value);

else

{

printf("类型不匹配!您试图用dbfgetFloatByIndex去写入非Float或int型字段\n");

return -3;

}

}

field=field->next;

}

printf("没有此索引index=%d\n",index);

return -1;

}

int dbfsetFloatByName(DBF_CONFIG * con,DBF_RECORD * record,char* name,void * value)

{

DBF_FIELD* field=con->head;

char field_type;

int index=0;

while(field!=NULL)

{

if((field->FIELD_LENTH>0)&&(strncmpi(field->FIELD_NAME,name,strlen(name)<field->FIELD_LENTH?strlen(name):field->FIELD_LENTH)==0))

{

if(field->FIELD_TYPE=='N'||field->FIELD_TYPE=='F')

{

index=field->index;

break;

}

else

{

printf("类型不匹配!您试图用dbfgetFloatByName去写入非Float或int型字段\n");

return -3;

}

}

field=field->next;

}

if(index==0)

{

printf("没有此列名称name=%s\n",name);

return -2;

}

return dbfsetFieldByIndex(con,record,index,value);

}

int dbfsetCharByIndex(DBF_CONFIG * con,DBF_RECORD * record,int index,void * value)

{

return dbfsetFieldByIndex(con,record,index,value);

}

int dbfsetCharByName(DBF_CONFIG * con,DBF_RECORD * record,char* name,void * value)

{

return dbfsetFieldByName(con,record,name,value);

}

void main()

{

dbf_info();

}

/************************************工具函数**********************************************/

char *ccstr( char *str)

{

char *tok = " ", *p;

p = strtok( str, tok );

while( p != NULL)

{

if( p != str )

strcat( str, p );

p = strtok( NULL, tok );

}

return( str );

}

3:结束

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有