gdbm編程示例


我在ubuntu是需要先安裝GDBM的。

總結一下GDBM的特點:

  1. 按key-value存儲數據,value是可變長的。它只對key進行索引,只能按key進行查詢。
  2. 高效的查詢,低效的插入,適合於存儲比較靜態的數據。
  3. GDBM可以很容易地編譯進一個可發布的二進制文件中,不需要獨立地安裝數據庫服務器。
  4. 不支持SQL,不支持表之間創建關系,更不用說存儲過程、觸發器什么的了。

操作GDBM就跟操作文件很相似,下面的代碼用於創建一個數據庫,並存入一條記錄。

#include<gdbm.h>
#include<stdlib.h>
#include<stdio.h>
#include<sys/stat.h>
#include<string.h>

#define ISBN_MAX 13
#define AUTHOR_MAX 50
#define TITLE_MAX 50
#define DB_FILE_BLOCK "book_data"

typedef struct {		/*定義圖書結構體 */
	char isbn[ISBN_MAX + 1];
	char author[AUTHOR_MAX + 1];
	char title[TITLE_MAX + 1];
	int numb;
} book_entry;

int main()
{
	book_entry newbook;	/*創建新的圖書記錄,並賦值 */
	memset(&newbook, '\0', sizeof(newbook));
	strncpy(newbook.isbn, "9787302184942", ISBN_MAX);
	strncpy(newbook.author, "Microsoft Research Asia", AUTHOR_MAX);
	strncpy(newbook.title, "Microsoft's Dream Works", TITLE_MAX);
	newbook.numb = 735;

	datum key, data;	/*datum結構體有兩個成員:dptr指向存儲的數據,dsize記錄數據的大小 */
	key.dptr = (char *)newbook.isbn;	/*用ISBN作key */
	key.dsize = ISBN_MAX;
	data.dptr = (char *)&newbook;	/*用整條數據記錄作value */
	data.dsize = sizeof(newbook);

	GDBM_FILE dbm_ptr;
	/*打開數據庫(跟打開文件很相似),返回數據庫句柄 */
	dbm_ptr = gdbm_open(DB_FILE_BLOCK,	/*文件名 */
			    0,	/*文件大小,設為0時GDBM將使用文件系統的統計塊大小 */
			    GDBM_WRCREAT,	/*讀寫模式。WRCREAT讀寫,數據庫文件不存在時創建;READER讀;WRITER寫 */
			    S_IRUSR | S_IWUSR,	/*權限標志位 */
			    NULL	/*出錯時的空參數回調函數 */
	    );
	/*把記錄存入數據庫 */
	gdbm_store(dbm_ptr,	/*數據庫句柄 */
		   key,		/*key值 */
		   data,	/*value值 */
		   GDBM_REPLACE	/*如果是GDBM_INSERT則插入重復記錄會出錯;GDBM——REPLACE則只是覆蓋原先存在的相同記錄 */
	    );

	char isbnarr[ISBN_MAX + 1] = { 0 };
	char *isbn = isbnarr;
	puts("請輸入你要查詢圖書的ISBN號:");
	scanf("%s",isbn);
	key.dptr = (char *)isbn;
	key.dsize = ISBN_MAX;
	/*數據庫查詢 */
	data = gdbm_fetch(dbm_ptr, key);	/*參建:數據庫句柄的key值 */
	if (data.dsize == 0)
		printf("查無結果\n");
	else {
		memset(&newbook, 0, sizeof(newbook));
		memcpy(&newbook, data.dptr, data.dsize);	/*將從數據庫讀到的記錄賦給book_entry結構體 */
		printf("%s\t%s\t%s\t%d\n", newbook.isbn, newbook.author,
		       newbook.title, newbook.numb);
	}

	/*關閉數據庫 */
	gdbm_close(dbm_ptr);
}

由於GDBM只支持按key查詢,如果我們想持按data中的某個字段查詢,就必須自己遍歷數據庫,逐一地和記錄(這是個struct)的特定成員進行對比。

我們通過兩個函數來遍歷數據庫:

gdbm_firstkey(dbm_ptr)    獲取數據庫第一條記錄的key值

gdbm_nextkey(dbm_ptr, key)  獲取下一條記錄的key值

要想實現模糊查詢也只能借助於strstr()函數,它用於判斷子串是否在主串中出現過。當然調用strstr之前,你通常還需要統計轉換為大寫或者小寫,tolower和touper可以對單個字符進行大小寫轉換。

下面的代碼就是遍歷數據庫,進行模糊查詢。

#include<string.h>
#include<stdlib.h>
#include<sys/stat.h>
#include<gdbm.h>
#include<stdio.h>
#include<ctype.h>

#define DB_FILE_BLOCK "book_data"
#define ISBN_MAX 13
#define AUTHOR_MAX 50
#define TITLE_MAX 50
#define FILED_MAX 50		/*最寬的數據域 */

typedef struct {
	char isbn[ISBN_MAX + 1];
	char author[AUTHOR_MAX + 1];
	char title[TITLE_MAX + 1];
	int numb;
} book_entry;

char *str_con(char *input, int len)
{
	int count = 0;
	do {
		input[count] = tolower(input[count]);
		count++;
	} while (count <= len);
	return input;
}

int main()
{
	GDBM_FILE dbm_ptr;
	datum key, data;
	book_entry vbook, sbook;/*vbook存儲數據庫中的原始記錄,sbook是轉換成小寫以后的*/ 
	char keyword[FILED_MAX];
	printf("請輸入一個關鍵字開始模糊查詢:");
	scanf("%s",keyword);
	dbm_ptr = gdbm_open(DB_FILE_BLOCK, 0, GDBM_READER, 0, NULL);
	for (key = gdbm_firstkey(dbm_ptr); key.dptr;
	     key = gdbm_nextkey(dbm_ptr, key)) {
		data = gdbm_fetch(dbm_ptr, key);
		memcpy(&sbook, data.dptr, data.dsize);
		memcpy(&vbook, data.dptr, data.dsize);
		strcpy(keyword, str_con(keyword, FILED_MAX));
		strcpy(sbook.isbn, str_con(sbook.isbn, ISBN_MAX));
		strcpy(sbook.title, str_con(sbook.title, TITLE_MAX));
		strcpy(sbook.author, str_con(sbook.author, AUTHOR_MAX));
		if ((strstr(sbook.isbn, keyword) || strstr(sbook.title, keyword)
		     || strstr(sbook.author, keyword))) {
			printf("%s\t%s\t%s\t%d\n", vbook.isbn, vbook.author,
			       vbook.title, vbook.numb);
		} else {
			printf("查無記錄\n");
		}
		gdbm_close(dbm_ptr);

	}
	return 0;
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM