-4

我已经用 VCPKG 安装了 Berkeley DB。

我正在尝试使用 Berkeley DB 存储简单的键值。像

水果 = 苹果

#include <sys/types.h>
#include <stdio.h>
#include <db.h>
#include <stdlib.h>
#include <vcruntime_string.h>
#include <iostream>

#define DATABASE "access.db"

using namespace std;

int main()
{
    DB* dbp;
    DBT key, data;
    int ret;
    if ((ret = db_create(&dbp, NULL, 0)) != 0)
    {
        fprintf(stderr, "db_create: %s\n", db_strerror(ret));
        cout << "db_create :" << db_strerror(ret) << endl;
    }
    else
        cout << "db_created or exists" << endl;

    if ((ret = dbp->open(dbp,
        NULL, DATABASE, NULL, DB_BTREE, DB_CREATE, 0664)) != 0) {
        dbp->err(dbp, ret, "%s", DATABASE);
        cout << "can not open db" << DATABASE << endl;
    }
    else {
        cout << "opened " << DATABASE << endl;
    }
    const char* fruit = "fruit";
    const char* apple = "apple";
    memset(&key, 0, sizeof(key));
    memset(&data, 0, sizeof(data));
    key.data = &fruit;
    key.size = sizeof(fruit);
    data.data = &apple;
    data.size = sizeof(apple);

    if ((ret = dbp->put(dbp, NULL, &key, &data, 0)) == 0)
        cout << "db: key stored :" << (const char*)key.data << endl;
    else
        dbp->err(dbp, ret, "DB->put");

    DBT key1, value1;
    memset(&key1, 0, sizeof(key1));
    memset(&value1, 0, sizeof(value1));
    key1.data = &fruit;
    key1.size = sizeof(fruit);

    if ((ret = dbp->get(dbp, NULL, &key1, &value1, 0)) == 0)
        cout << "db: value fetched :" << (const char*)value1.data << endl;
    else
        dbp->err(dbp, ret, "DB->get");

    return 0;
}

数据库事务DBT实例需要一个 void 指针void *作为输入,所以我传递了引用。该代码有效,但是当我从中转换数据值DBT时显示垃圾/难以辨认的字符。我不知道问题是什么

输出

db: key stored :£┴₧÷
db: value fetched :ñ┴₧÷

我尝试过的事情:

  • 与 (string *) 一起使用强制转换
db: key stored :000000C6B78FFC68
db: value fetched :0000025996F56C70
  • 使用 (char *) 投射
db: key stored :£┴┘à÷
db: value fetched :ñ┴┘à÷
  • 使用 (const char *) 强制转换
db: key stored :£┴₧÷
db: value fetched :ñ┴₧÷
  • 使用 *(const char *) 强制转换
db: key stored :£
db: value fetched :ñ
  • 在 Notepad++ 中粘贴值并更改编码以查看它是否根据需要提供纯文本

如何从 Berkeley DB 获取可读文本?我在存储数据本身时做错了吗?

我是 C++ 的初学者,所以我没有别的事可做。

4

2 回答 2

0
const char* fruit = "fruit";

这意味着是您平台上sizeof(fruit)的 a 的大小。const char *这也意味着&fruit这个特定指针存储在您的平台上的位置。鉴于这两件事:

data.data = &apple;
data.size = sizeof(apple);

这两条线都没有任何意义。您应该将指向数据的指针放在 中data,而不是指向 a 的指针const char *。您应该将数据的大小放入 中size,而不是 a 的大小const char *

尝试:

data.data = (void *) apple;
data.size = strlen(apple);
于 2019-08-09T22:30:35.370 回答
-2

解决方案是将键值的数据类型从常量字符指针const char *更改为 char 数组。

char fruit[sizeof("fruit")] = "fruit";
char apple[sizeof("apple")] = "apple";

此外,即使使用string而不是const char *键值会给出与问题中提到的类似的问题,但我可以以某种方式使其仅适用于 char 数组。参考:BerkeleyDB.example

于 2019-08-12T14:16:44.653 回答