简体   繁体   English

无法从 c 中不同 function 的 GDBM 数据库中检索数据

[英]Unable to retrive data from GDBM databas from differnt function in c

hi there i am trying to develop 3 tier server with embedded database.您好,我正在尝试开发带有嵌入式数据库的 3 层服务器。

my issue is that i am able to save data in gdbm database but when i try to retrieve data from other functions it always returns null value.我的问题是我能够将数据保存在 gdbm 数据库中,但是当我尝试从其他函数检索数据时,它总是返回 null 值。 i have also point out the issue which is the null termination (verified through gdb output) of key value while i am saving data key does not ends with \0 but while retrieving data it is terminated by \0 i am not quite sure about this theory and don't know how to solve it.我还指出了问题是 null 终止(通过 gdb 输出验证)的键值,而我正在保存数据键不以 \0 结尾,但在检索数据时它被 \0 终止我不太确定这一点理论不知道怎么解决。

things that i have tried:我尝试过的事情:

  • tried to add null character manually but did not worked尝试手动添加 null 字符但没有用
  • tired to remove null character from key but it still does not work.厌倦了从键中删除 null 字符,但它仍然不起作用。
  • tried to get key from same structure hoping that issue may be due to different format but did not worked试图从相同的结构中获取密钥,希望问题可能是由于格式不同但没有奏效
  • tried to replace null character but did not helped because i don't know what i am doing wrong and why at the time of saving data there is no null character.试图替换 null 字符但没有帮助,因为我不知道我做错了什么以及为什么在保存数据时没有 null 字符。

i have attached minimum code to reproduce same error hope so someone will point out my mistake in the mean time i will still try to resolve this issue but your guideline can be helpful.我附上了重现相同错误的最少代码,希望有人会指出我的错误,同时我仍会尝试解决此问题,但您的指南可能会有所帮助。

source Code源代码

#include <gdbm.h>
#include <string.h>
#include <stdio.h>

#define STR_SIZE 20
#define BUFFER_SIZE 256
typedef struct UserData
{
    char name[STR_SIZE];
    char accountNumber[STR_SIZE];
    char password[STR_SIZE];
    long balence;
} userData;

void simulateSelect(GDBM_FILE dbFile);
void simulateInsert(GDBM_FILE dbFile);

int main(int argc, char **argv)
{
    GDBM_FILE dbFile = gdbm_open("newSampleDB", 0, GDBM_WRCREAT | GDBM_READER, 0660, 0);
    simulateInsert(dbFile);
    simulateSelect(dbFile);
    return 0;
}

void simulateInsert(GDBM_FILE dbFile)
{
    //RPC call data sent to server [function mode [data for function call]
    char *request = "signup user fawad 10120 11223 120";

    //server receiving end
    char buffer[BUFFER_SIZE];
    char name[STR_SIZE];
    char id[STR_SIZE];
    char pass[STR_SIZE];
    char bal[STR_SIZE];
    char temp[STR_SIZE];
    char mode[STR_SIZE];
    //parse cliet request and slect one of the avaiable opertaion
    sscanf(request, "%s %s %s %s %s %s", temp, mode, name, id, pass, bal);
    bzero(buffer, BUFFER_SIZE);
    //forward request to database server
    sprintf(buffer, "insert %s %s %s %s %s", mode, name, id, pass, bal);
    // databse server receiving end
    userData data;
    bzero(name, STR_SIZE);
    bzero(id, STR_SIZE);
    bzero(pass, STR_SIZE);
    //parse request and take actoin
    sscanf(buffer, "%s %s %s %s %s %li", temp, temp, name, id, pass, &data.balence);
    strcpy(data.name, name);
    strcpy(data.accountNumber, id);
    strcpy(data.password, pass);
    //save data in database
    datum key;
    // i have checked through gdb at this point key.dptr does not have null termination i.e. \0
    // key.dptr = 10120
    key.dptr = data.accountNumber;
    key.dsize = STR_SIZE + 1;
    datum _data;
    _data.dptr = (char *)&data;
    _data.dsize = sizeof(data);
    int res = gdbm_store(dbFile, key, _data, GDBM_INSERT);
    printf("Indert Status = %d", res);
    //works fine here and data is retrived
    datum data3 = gdbm_fetch(dbFile, key);
    userData *data1 = (userData *)(data3.dptr);
    sprintf(buffer, "1 %s %s %s %li", data1->name, data1->accountNumber, data1->password, data1->balence);
    fprintf(stdout, "%s", buffer);
}

void simulateSelect(GDBM_FILE dbFile)
{
    //client again initiates request to login
    char *request = "login user 10120 11223";
    //server end
    char buffer[BUFFER_SIZE];
    char id[STR_SIZE];
    char pass[STR_SIZE];
    char temp[STR_SIZE];
    char mode[STR_SIZE];
    bzero(buffer, BUFFER_SIZE);
    //parse request and select operatoin
    sscanf(request, "%s %s %s %s", temp, mode, id, pass);
    //send request to database server
    sprintf(buffer, "select %s %s", mode, id);
    //databse server end
    bzero(id, STR_SIZE);
    //parse request
    sscanf(buffer, "%s %s %s", temp, mode, id);
    // userData d;
    // strcpy(d.accountNumber, id);
    datum _data;
    datum key;
    // at this point key.dptr have null termiantion i.e key.dptr= 10120\0
    key.dptr = id;
    // key.dptr = d.accountNumber;
    key.dsize = STR_SIZE + 1;
    _data = gdbm_fetch(dbFile, key);
    userData *data = (userData *)(_data.dptr);
    // ((userData *)res.dptr)->name)
    sprintf(buffer, "1 %s %s %s %li", data->name, data->accountNumber, data->password, data->balence);
    fprintf(stdout, "%s", buffer);
}

The problem is very likely that you use the whole (and more!) of the accountNumber array as key, even the parts beyond the string null-terminator which will be uninitialized and have indeterminate values.问题很可能是您使用accountNumber数组的整个(以及更多!)作为键,甚至是字符串空终止符之外的部分,这些部分将未初始化并具有不确定的值。

The key you use when you write will thus likely not be exactly the same as the one you use when reading the data.因此,您在写入时使用的密钥可能与您在读取数据时使用的密钥不完全相同。

The solution is to make sure that all of the accountNumber array will be initialized (as in memset(data.accountNumber, 0, sizeof data.accountNumber) ) before copying the string to it.解决方案是确保在将字符串复制到它之前,将初始化所有accountNumber数组(如在memset(data.accountNumber, 0, sizeof data.accountNumber) )。


The problem with eg例如的问题

bzero(id, STR_SIZE);
// ...
strcpy(data.accountNumber, id);

is that strcpy will not copy data beyond the string null-terminator, so it doesn't copy the full array id , only a small part of it.strcpy不会复制字符串空终止符之外的数据,因此它不会复制完整的数组id ,只复制其中的一小部分。 Which will leave the remaining elements of data.accountNumber uninitialized.这将使data.accountNumber的其余元素未初始化。

You must initialize data.accountNumber itself.您必须初始化data.accountNumber本身。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM