[英]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:我尝试过的事情:
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.