?? c語言寫的.dbf文件的操作函數庫.txt
字號:
為什么編寫本函數庫?
目前好多電力方面的抄表器由于其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)
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -