VC下如何操作DBF(FoxPro数据库)文件? 如题,可以再加分。 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 先用SqlConfigDataSource函数建立一个FoxPro文件想对应的文件数据源, 然后通过这个ODBC数据源对文件访问.用CDataBase + CRecordset + sql语句就可以了, 想怎么访问就怎么访问. 参考:http://sanjianxia.diy.myrice.com/vc/vc1.htm http://www.vchelp.net/vchelp/archive.asp?type_id=50&class_id=1&cata_id=10&article_id=786&search_term= http://www.csdn.net/cnshare/soft/15/15429.shtm ifndef __YB_DEFINE_DBF_H__#define __YB_DEFINE_DBF_H__#include <stdio.h>#include <stdlib.h>#include <fcntl.h>#include <time.h>#include <string.h>#ifdef WIN32 #include <sys\stat.h> #include <sys\types.h> #include <sys\locking.h> #include <share.h> #include <dos.h> #include <io.h> #define snprintf _snprintf#else #include <sys/stat.h> #include <unistd.h> #include "xntoy.h" #define O_BINARY 0#endif//*************************************************************// DBF读写类库跨平台版本,在windows、linux、Sco下编译通过。// 修改:袁斌 // [email protected]// http://yb.nos.com.cn/index.html// 时间:2000年4月11日// bug report: 内部->[email protected] // 外部->[email protected]//// 主要修改内容:// 一、速度方面的修改。// 1、将原先通过多个sprintf、sscanf等写一条记录的方式改为// 通过调用xntoy系列函数取代,速度提高不少。// 2、将原先采用单链表方式组织的字段结构改成hash链表方式,// 查找字段基本上为常数级别O(1),速度有一定提高。//// 二、安全性方面的修改。// 1、使用snprintf取代以前的sprintf。// 2、使用xntoy系列函数保证缓冲区不越界。//// 三、移植性方面的修改。// 1、将全部_???函数换成???函数。// 2、将全部_???参数换成???参数。// 3、针对Linux下面没有的几个函数在xntoy里面作了实现。//// 四、其它修改内容。// 1、将函数位置进行了调整,相同功能部分放在了一起。// 2、将函数名称进行了调整,基本上采用ODBC一致的名称。// 3、将有副作用的Append函数和读字段值函数进行了调整。// 4、对相关数据结构进行了调整。// 5、对一次读写多条记录的函数及相关内容全部删除。//*************************************************************#define max(a,b) ((a<b) ? b : a)#define min(a,b) ((a<b) ? a : b)#pragma comment(exestr, "yb/oldworm cross platform dbf class 2000/04/11 ")char * formatstr(char *s);char * Trim(char *str);typedef long BOOL;typedef unsigned short ushort;typedef unsigned int uint;typedef unsigned char uchar;typedef unsigned long ulong;enum{ MAX_FIELDS = 256};enum{ FALSE = 0, TRUE = 1};enum { RDONLY = 0x01, // 只读流览 RDWR = 0x02 // 可读写流览};enum{ EQUAL = 1, GREATER = 2, GREATER_OR_EQUAL= 3, LESS = 4, LESS_OR_EQUAL = 5};struct _dosdate_t{ uint year; uint month; uint day;};typedef struct{ uchar dbf_id; // dbf_id=03, memo field does not exist // dbf_id=83, memo field exists( foxbase ) // dbf_id=F5, memo field exists ( foxpro ) char last_update[3]; // year,month,date of the file last_update long last_rec; // serial number of the last record ushort data_offset; // the start address of the data item ushort rec_size; // the record size = all fields size + 1 char filler[20]; // unused} DBF_HEAD;typedef struct{ char field_name[11]; char field_type; char dummy[4]; // unused union { ushort wlen; // when the field type is not numeric struct { uchar len; uchar dec; }N; // when the field type is numeric } linfo; char filler[14]; // unused}FIELD_REC;typedef struct FIELD_LIST{ FIELD_REC field_rec; //字段内容 char *cname; //该字段对应的中文名称 int m_start; //}FIELD_LIST;typedef struct FIELD_HASHNODE FIELD_HASHNODE;struct FIELD_HASHNODE{ ushort index; FIELD_HASHNODE *next;};typedef struct { int handle; //Dbf文件句柄 char * file_name; // long curr_rec; //当前记录 DBF_HEAD dbf_head; //文件头部 FIELD_LIST * field_list[MAX_FIELDS]; FIELD_HASHNODE *field_hashnode[MAX_FIELDS]; ushort field_num; //字段数目 char *record_buf; //记录缓冲}DBF_HANDLE;typedef class Dbf DBF;typedef class Dbf DBFFILE;class Dbf {public : DBF_HANDLE * dbf_handle; Dbf(); ~Dbf();public: /************************************************************************** 功 能: 打开一数据文件 传入参数: filename ---- 文件名 fptFilename ---- 备注文件名, 缺省为库文件+FPT后缀 返 回: TRUE -- 成功 FALSE -- 失败 ***************************************************************************/ BOOL Open(const char * filename,char openway=RDWR ); //关闭数据库文件。 void Close(void ); // 根据指定字段列表创建DBF库 BOOL Create(const char * filename, FIELD_REC * field ); // 删除DBF库中的全部记录,仅保留字段和数据库头部。 BOOL Zap( void );public: //////////////////////////////////////////////////////////////////////// //field function static void AddField(FIELD_REC &field_rec,const char *fieldname, char fieldtype,ushort len,uchar dec=0); void SetFieldCName( char * field_name , char * fieldChName ) ; BOOL GetFieldName(char *sa[], int item_size, int item_num); //取全部字段名称列表。 FIELD_LIST * look_field(const char *field_name); //////////////////////////////////////////////////////////////////////// //cursor function BOOL Move( long rec_num ); // 把当前记录指针移到指定记录号, 并读取内容 BOOL MoveFirst( void ); // 把当前记录指针移到第一条记录, 并读取内容 BOOL MoveNext( long rec_num = 1L ) ; // 把当前记录指针移到下一条记录,并读取记录内容 BOOL MoveLast( void ); //record function long RecNo() ; // 返回当前记录号 long GetRecordCount( ); // 返回当前记录数 long ReadRecordCount( void ) ; // 重读文件,获取当前记录数 void ClearRecBuf( void ) ; // 清记录内存缓冲 char *RecordBuf( void ); // 返回当前记录缓冲指针 //Lock Function void SetLock ( void ){ lock = 1; }; void SetUnLock( void ){ lock = 0; }; //////////////////////////////////////////////////////////////////////// BOOL Append(const char *id_fname=NULL); // 追加记录 BOOL Update(long rec_num = 0L); //用当前记录缓冲内容修改指定记录, 0表示修改当前记录 BOOL AppendBlank(void); //追加一条空记录 BOOL Delete(long rec_num =0) ; //设置删除标志。rec_num = 0 表示当前记录。 BOOL IsDelete( void ); //判断当前记录是否有删除标记 char *FileName( void ) //返回当前数据库名 { if( dbf_handle != NULL ) return (dbf_handle->file_name) ; else return "\0" ; } BOOL IsOpen() {//测试是否 DBF FILE 已经正常打开。 return ( dbf_handle!=NULL && dbf_handle->handle!=-1 ); }public: //////////////////////////////////////////////////////////////////////// //以下函数取指定字段的值 char * GetFieldValue (const char *field_name, char *fieldvalue, int size, BOOL bFormat=TRUE,char * field_type=NULL); BOOL GetFieldValue(const char *field_name, long &value); BOOL GetFieldValue(const char *field_name, int &value); BOOL GetFieldValue(const char *field_name, short &value); BOOL GetFieldValue(const char *field_name, float &value); BOOL GetFieldValue(const char *field_name, double &value); //////////////////////////////////////////////////////////////////////// // 修改指定字段的内容 BOOL SetFieldValue(const char * field_name , const char * field_value ); BOOL SetFieldValue(const char * field_name , long field_value ); BOOL SetFieldValue(const char * field_name , int field_value ); BOOL SetFieldValue(const char * field_name , short field_value ); BOOL SetFieldValue(const char * field_name , float field_value ); BOOL SetFieldValue(const char * field_name , double field_value );private: inline BOOL insert_field_hashnode(FIELD_HASHNODE *pnode); inline BOOL _SetFieldValue(FIELD_LIST *flist_ptr , const char * field_value); inline BOOL _Update(long rec_num = 0L, int size=0); inline void _SetDosDate(DBF_HEAD *phead); inline short FieldLen( FIELD_LIST * flist_ptr ) ; int read_dbfhead( void ); BOOL lock_dbf_rec( long rec, long RecNum ); BOOL unlock_dbf_rec( long rec, long RecNum ); BOOL lock_dbf_file( void ); BOOL unlock_dbf_file( void ); BOOL lock_dbf_head( void ); BOOL unlock_dbf_head( void ); BOOL LockFile( long offset, long rec_size ); BOOL UnlockFile( long offset, long rec_size );private: int open_way; //文件 //*************************************************************// DBF读写类库跨平台版本,在windows、linux、Sco下编译通过。// 修改:袁斌 // [email protected]// http://yb.nos.com.cn/index.html// 时间:2000年4月11日// bug report: 内部->[email protected] // 外部->[email protected]//// 主要修改内容:// 一、速度方面的修改。// 1、将原先通过多个sprintf、sscanf等写一条记录的方式改为// 通过调用xntoy系列函数取代,速度提高不少。// 2、将原先采用单链表方式组织的字段结构改成hash链表方式,// 查找字段基本上为常数级别O(1),速度有一定提高。//// 二、安全性方面的修改。// 1、使用snprintf取代以前的sprintf。// 2、使用xntoy系列函数保证缓冲区不越界。//// 三、移植性方面的修改。// 1、将全部_???函数换成???函数。// 2、将全部_???参数换成???参数。// 3、针对Linux下面没有的几个函数在xntoy里面作了实现。//// 四、其它修改内容。// 1、将函数位置进行了调整,相同功能部分放在了一起。// 2、将函数名称进行了调整,基本上采用ODBC一致的名称。// 3、将有副作用的Append函数和读字段值函数进行了调整。// 4、对相关数据结构进行了调整。// 5、对一次读写多条记录的函数及相关内容全部删除。//************************************************************* 我们在用VC++进行基于数据的综合开发时,会经常访问到大量的物理存储位置不可预见的FoxPro数据表(.DBF文件)。 这时,我们就要使用到动态加载ODBC的技术去访问这些数据表。 ■技术要点分析 使用ODBC技术时,要求程序开发人员能预先确定数据源的位置,利用“控制面板”中的“ODBC管理器”手工加载数据库。 但在实际的开发中,特别是基于Client/Server网络环境的综合开发中,往往无法确定数据源的位置,而只能进行动态加载。 对于这种情况,我们可以使用一个Windows API函数 SQLConfigDataSource( )来完成这一操作。 ■应用举例 先用FoxPro生成一张数据表Member.dbf,并设计好各项字段。注意字段名用英文,否则在VC++中使用时会出现错误。 接着利用Visulal C++ 的向导生成一个基于对话框的程序,命名为DBFDemo。修改主对话框,如图所示。 利用ClassWizard为程序加入一个基类为CRecordset的名为CUserInfo的新类,按照向导的指示,取得Member.dbf的表结构。 在类CUserInfo的头文件上加入两个文件包含语句: #include "afxdb.h" #include "odbcinst.h" 下面给出范例程序的关键代码: BOOL CDBFDemoDlg::OnInitDialog() //主对话框的初始化函数 { ……//省略部分机器生成代码 //下面一句开始动态增加一个ODBC驱动 SQLConfigDataSource(NULL,ODBC_ADD_DSN,"Microsoft Visual FoxPro Driver", "DSN=UserInfo\0Description=UserInfo\ 0SourceType=dbf\0Source=d:\\DBF\0"); Database.Open(_T("UserInfo")); //打开ODBC驱动,Database派生于CDatabase类 UserInfo.m_pDatabase=&&Database; //设置与CDatabase的连接,UserInfo派生于CUserInfo类 UserInfo.Open(AFX_DB_USE_DEFAULT_TYPE, "SELECT FROM member",CRecordset::none); return TRUE; } void CDBFDemoDlg::GetRecordValue() { //这个函数取得打开的表中的记录,并利用DDX/DDV机制相应设置对话框中的各控件 m_Order=UserInfo.m_order; //取得记录中各字段的值,并设置相应的控件值 m_Name=UserInfo.m_name; m_Age=UserInfo.m_age; m_Addr=UserInfo.m_addr; if(UserInfo.m_sex==TRUE) //典型的设置记录中类型为BOOL型的字段的操作 this-〉CheckRadioButton(IDB_MAN,IDB_WOMAN,IDB_MAN); else this-〉CheckRadioButton(IDB_MAN,IDB_WOMAN,IDB_WOMAN); UpdateData(FALSE); //将记录信息显示在对话框中 } void CDBFDemoDlg::OnNext() //按钮“下一个”的响应函数 { if(!UserInfo.IsEOF()) //测试记录是否到底部 { UserInfo.MoveNext(); //向下移动一个记录 GetRecordValue(); //设置对话框中的记录显示 } else { //报告到达最末记录信息 ::MessageBox(this-〉m_hWnd,"到达最末记录","消息框",MB_OK); UserInfo.MovePrev(); //若到最末记录,上移一个记录,避免空操作 } } void CDBFDemoDlg::OnPrev() //按钮“下一个”的响应函数 { if(!UserInfo.IsBOF()) //测试记录是否到达顶部 { UserInfo.MovePrev(); //向上移动一个记录 GetRecordValue(); //设置对话框中的记录显示 } else { //报告到达首记录 ::MessageBox(this-〉m_hWnd,"到达首记录","消息框",MB_OK); UserInfo.MoveNext(); } } void CDBFDemoDlg::SetRecordValue() {//这个函数根据对话框中各控件的值设置数据表中的某个记录的各字段值 UpdateData(TRUE); //利用DDX/DDV机制取得控件中的值 UserInfo.m_order=m_Order; UserInfo.m_name=m_Name; UserInfo.m_addr=m_Addr; UserInfo.m_sex=Sex; //变量Sex可以取得“性别”一项中所选的值 UserInfo.m_age=m_Age; UserInfo.Update(); //更新记录的值 } void CDBFDemoDlg::OnApply() //按钮“应用”的响应函数 { //这个函数可以进行用户所选择的如“新增用户”、“修改用户”、“删除用户”的操作 switch(Operator) //变量Operator的值由用户的选择而决定 { case ADD: //宏“ADD”已经在程序开头时进行了定义 if(UserInfo.CanAppend()==TRUE) UserInfo.AddNew(); //新增用户 SetRecordValue(); this-〉OnAdd(); break; case MODI: //修改用户信息 UserInfo.Edit(); SetRecordValue(); break; case DELE: //删除用户 if(UserInfo.IsDeleted()==FALSE) { UserInfo.Delete(); this-〉OnPrev(); } break; default: //用户没有进行操作选择 ::MessageBox(this-〉m_hWnd,"请选择你所要进行的操作","忘记选择操作",MB_OK); break; } } 限于篇幅,笔者只列出其主要代码,读者可以根据这些关键代码完成这个范例程序。 程序在中/英文Windows 98、VC++ 6.0环境下编译通过,运行正常。需要注意的是, 由于范例中使用的是Visual FoxPro 6.0的ODBC驱动器,所以要试验这个程序,请先安装VFP 6.0。 用ADO以数据库方式打开DBF,JET 4.0 用ADO以数据库方式打开DBF,JET 4.0 PHOTOSHOP的右半边的常在窗口是怎么做的? mfc 按钮背景效果 help!在学习孙鑫教程线程一课遇到的问题,混乱! VC下对图片的操作问题 只要一用CFiledialog,下面这段代码fopen就会失败 [精华区]的贴子都到那去了? 一个用REMOTE的添加记录的问题 为什么我的编译器VC++6总是再编译时不能识别用户写的头文件? mfc加载idl32.dll失败 如何获得cpu信息? 请问:插入/资源中的Dialog下不同选项的作用是什么? 调用dll的输出函数问题
用CDataBase + CRecordset + sql语句就可以了, 想怎么访问就怎么访问.
http://sanjianxia.diy.myrice.com/vc/vc1.htm
#define __YB_DEFINE_DBF_H__#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <time.h>
#include <string.h>#ifdef WIN32
#include <sys\stat.h>
#include <sys\types.h>
#include <sys\locking.h>
#include <share.h>
#include <dos.h>
#include <io.h>
#define snprintf _snprintf
#else
#include <sys/stat.h>
#include <unistd.h>
#include "xntoy.h"
#define O_BINARY 0
#endif//*************************************************************
// DBF读写类库跨平台版本,在windows、linux、Sco下编译通过。
// 修改:袁斌
// [email protected]
// http://yb.nos.com.cn/index.html
// 时间:2000年4月11日
// bug report: 内部->[email protected]
// 外部->[email protected]
//
// 主要修改内容:
// 一、速度方面的修改。
// 1、将原先通过多个sprintf、sscanf等写一条记录的方式改为
// 通过调用xntoy系列函数取代,速度提高不少。
// 2、将原先采用单链表方式组织的字段结构改成hash链表方式,
// 查找字段基本上为常数级别O(1),速度有一定提高。
//
// 二、安全性方面的修改。
// 1、使用snprintf取代以前的sprintf。
// 2、使用xntoy系列函数保证缓冲区不越界。
//
// 三、移植性方面的修改。
// 1、将全部_???函数换成???函数。
// 2、将全部_???参数换成???参数。
// 3、针对Linux下面没有的几个函数在xntoy里面作了实现。
//
// 四、其它修改内容。
// 1、将函数位置进行了调整,相同功能部分放在了一起。
// 2、将函数名称进行了调整,基本上采用ODBC一致的名称。
// 3、将有副作用的Append函数和读字段值函数进行了调整。
// 4、对相关数据结构进行了调整。
// 5、对一次读写多条记录的函数及相关内容全部删除。
//*************************************************************#define max(a,b) ((a<b) ? b : a)
#define min(a,b) ((a<b) ? a : b)#pragma comment(exestr, "yb/oldworm cross platform dbf class 2000/04/11 ")char * formatstr(char *s);
char * Trim(char *str);typedef long BOOL;
typedef unsigned short ushort;
typedef unsigned int uint;
typedef unsigned char uchar;
typedef unsigned long ulong;enum
{
MAX_FIELDS = 256
};enum
{
FALSE = 0,
TRUE = 1
};enum
{
RDONLY = 0x01, // 只读流览
RDWR = 0x02 // 可读写流览
};enum
{
EQUAL = 1,
GREATER = 2,
GREATER_OR_EQUAL= 3,
LESS = 4,
LESS_OR_EQUAL = 5
};struct _dosdate_t
{
uint year;
uint month;
uint day;
};typedef struct
{
uchar dbf_id; // dbf_id=03, memo field does not exist
// dbf_id=83, memo field exists( foxbase )
// dbf_id=F5, memo field exists ( foxpro )
char last_update[3]; // year,month,date of the file last_update
long last_rec; // serial number of the last record
ushort data_offset; // the start address of the data item
ushort rec_size; // the record size = all fields size + 1
char filler[20]; // unused
} DBF_HEAD;
typedef struct
{
char field_name[11];
char field_type;
char dummy[4]; // unused
union
{
ushort wlen; // when the field type is not numeric
struct
{
uchar len;
uchar dec;
}N; // when the field type is numeric
} linfo;
char filler[14]; // unused
}FIELD_REC;
typedef struct FIELD_LIST
{
FIELD_REC field_rec; //字段内容
char *cname; //该字段对应的中文名称
int m_start; //
}FIELD_LIST;
typedef struct FIELD_HASHNODE FIELD_HASHNODE;struct FIELD_HASHNODE
{
ushort index;
FIELD_HASHNODE *next;
};
typedef struct
{
int handle; //Dbf文件句柄
char * file_name; //
long curr_rec; //当前记录
DBF_HEAD dbf_head; //文件头部
FIELD_LIST * field_list[MAX_FIELDS];
FIELD_HASHNODE *field_hashnode[MAX_FIELDS];
ushort field_num; //字段数目
char *record_buf; //记录缓冲
}DBF_HANDLE;
typedef class Dbf DBF;
typedef class Dbf DBFFILE;
class Dbf
{
public :
DBF_HANDLE * dbf_handle; Dbf();
~Dbf();
public:
/**************************************************************************
功 能: 打开一数据文件
传入参数: filename ---- 文件名
fptFilename ---- 备注文件名, 缺省为库文件+FPT后缀
返 回: TRUE -- 成功 FALSE -- 失败
***************************************************************************/
BOOL Open(const char * filename,char openway=RDWR );
//关闭数据库文件。
void Close(void );
// 根据指定字段列表创建DBF库
BOOL Create(const char * filename, FIELD_REC * field );
// 删除DBF库中的全部记录,仅保留字段和数据库头部。
BOOL Zap( void );
public:
////////////////////////////////////////////////////////////////////////
//field function
static void AddField(FIELD_REC &field_rec,const char *fieldname,
char fieldtype,ushort len,uchar dec=0);
void SetFieldCName( char * field_name , char * fieldChName ) ;
BOOL GetFieldName(char *sa[], int item_size, int item_num); //取全部字段名称列表。
FIELD_LIST * look_field(const char *field_name);
////////////////////////////////////////////////////////////////////////
//cursor function
BOOL Move( long rec_num ); // 把当前记录指针移到指定记录号, 并读取内容
BOOL MoveFirst( void ); // 把当前记录指针移到第一条记录, 并读取内容
BOOL MoveNext( long rec_num = 1L ) ; // 把当前记录指针移到下一条记录,并读取记录内容
BOOL MoveLast( void );
//record function
long RecNo() ; // 返回当前记录号
long GetRecordCount( ); // 返回当前记录数
long ReadRecordCount( void ) ; // 重读文件,获取当前记录数
void ClearRecBuf( void ) ; // 清记录内存缓冲
char *RecordBuf( void ); // 返回当前记录缓冲指针
//Lock Function
void SetLock ( void ){ lock = 1; };
void SetUnLock( void ){ lock = 0; };
////////////////////////////////////////////////////////////////////////
BOOL Append(const char *id_fname=NULL); // 追加记录
BOOL Update(long rec_num = 0L); //用当前记录缓冲内容修改指定记录, 0表示修改当前记录
BOOL AppendBlank(void); //追加一条空记录
BOOL Delete(long rec_num =0) ; //设置删除标志。rec_num = 0 表示当前记录。
BOOL IsDelete( void ); //判断当前记录是否有删除标记
char *FileName( void ) //返回当前数据库名
{
if( dbf_handle != NULL )
return (dbf_handle->file_name) ;
else
return "\0" ;
} BOOL IsOpen()
{//测试是否 DBF FILE 已经正常打开。
return ( dbf_handle!=NULL && dbf_handle->handle!=-1 );
}
public:
////////////////////////////////////////////////////////////////////////
//以下函数取指定字段的值
char * GetFieldValue (const char *field_name, char *fieldvalue, int size,
BOOL bFormat=TRUE,char * field_type=NULL);
BOOL GetFieldValue(const char *field_name, long &value);
BOOL GetFieldValue(const char *field_name, int &value);
BOOL GetFieldValue(const char *field_name, short &value);
BOOL GetFieldValue(const char *field_name, float &value);
BOOL GetFieldValue(const char *field_name, double &value);
////////////////////////////////////////////////////////////////////////
// 修改指定字段的内容
BOOL SetFieldValue(const char * field_name , const char * field_value );
BOOL SetFieldValue(const char * field_name , long field_value );
BOOL SetFieldValue(const char * field_name , int field_value );
BOOL SetFieldValue(const char * field_name , short field_value );
BOOL SetFieldValue(const char * field_name , float field_value );
BOOL SetFieldValue(const char * field_name , double field_value );
private:
inline BOOL insert_field_hashnode(FIELD_HASHNODE *pnode);
inline BOOL _SetFieldValue(FIELD_LIST *flist_ptr , const char * field_value);
inline BOOL _Update(long rec_num = 0L, int size=0);
inline void _SetDosDate(DBF_HEAD *phead);
inline short FieldLen( FIELD_LIST * flist_ptr ) ;
int read_dbfhead( void );
BOOL lock_dbf_rec( long rec, long RecNum );
BOOL unlock_dbf_rec( long rec, long RecNum );
BOOL lock_dbf_file( void );
BOOL unlock_dbf_file( void );
BOOL lock_dbf_head( void );
BOOL unlock_dbf_head( void );
BOOL LockFile( long offset, long rec_size );
BOOL UnlockFile( long offset, long rec_size );private:
int open_way; //文件
// DBF读写类库跨平台版本,在windows、linux、Sco下编译通过。
// 修改:袁斌
// [email protected]
// http://yb.nos.com.cn/index.html
// 时间:2000年4月11日
// bug report: 内部->[email protected]
// 外部->[email protected]
//
// 主要修改内容:
// 一、速度方面的修改。
// 1、将原先通过多个sprintf、sscanf等写一条记录的方式改为
// 通过调用xntoy系列函数取代,速度提高不少。
// 2、将原先采用单链表方式组织的字段结构改成hash链表方式,
// 查找字段基本上为常数级别O(1),速度有一定提高。
//
// 二、安全性方面的修改。
// 1、使用snprintf取代以前的sprintf。
// 2、使用xntoy系列函数保证缓冲区不越界。
//
// 三、移植性方面的修改。
// 1、将全部_???函数换成???函数。
// 2、将全部_???参数换成???参数。
// 3、针对Linux下面没有的几个函数在xntoy里面作了实现。
//
// 四、其它修改内容。
// 1、将函数位置进行了调整,相同功能部分放在了一起。
// 2、将函数名称进行了调整,基本上采用ODBC一致的名称。
// 3、将有副作用的Append函数和读字段值函数进行了调整。
// 4、对相关数据结构进行了调整。
// 5、对一次读写多条记录的函数及相关内容全部删除。
//*************************************************************