与memcpy连接
我正在尝试使用memcpy将两个字符串添加到一起。我要求第一个memcpy包含数据。然而,第二种方法并不适用。知道为什么吗与memcpy连接,c,string,memcpy,C,String,Memcpy,我正在尝试使用memcpy将两个字符串添加到一起。我要求第一个memcpy包含数据。然而,第二种方法并不适用。知道为什么吗 if (strlen(g->db_cmd) < MAX_DB_CMDS ) { memcpy(&g->db_cmd[strlen(g->db_cmd)],l->db.param_value.val,strlen(l->db.param_value.val)); memcpy(&g->db_cm
if (strlen(g->db_cmd) < MAX_DB_CMDS )
{
memcpy(&g->db_cmd[strlen(g->db_cmd)],l->db.param_value.val,strlen(l->db.param_value.val));
memcpy(&g->db_cmd[strlen(g->db_cmd)],l->del_const,strlen(l->del_const));
g->cmd_ctr++;
}
if(strlen(g->db\u cmd)db_cmd[strlen(g->db_cmd)],l->db.param_value.val,strlen(l->db.param_value.val));
memcpy(&g->db_cmd[strlen(g->db_cmd)],l->del_const,strlen(l->del_const));
g->cmd_ctr++;
}
您没有复制空终止符,您只是处理原始字符串数据。这会使字符串以非null结尾,这会导致各种问题。您也没有检查以确保缓冲区中有足够的空间,这可能会导致错误
要确保复制空终止符,只需在正在复制的字节数中添加1即可——复制
strlen(l->db.param_value.val)+1
字节。一个可能的问题是第一个memcpy()
调用不一定会导致以null结尾的字符串,因为您没有从l->db.param_value.val
复制'\0'终止符:
因此,当在对memcpy()
的第二次调用中调用strlen(g->db_cmd)
时,它可能返回了完全虚假的内容。这是否是一个问题取决于g->db\u cmd
缓冲区是否预先初始化为零
为什么不使用strcat()
,它正是为了完成您想用memcpy()执行的操作而设计的
如果strlcat()
不是您平台的一部分,那么可以很容易地在网上找到它。如果您使用的是MSVC,则可以使用一个strcat_s()
函数来代替它(但请注意,它并不等同于strlcat()
——您必须更改调用strcat_s()
的结果的检查和处理方式)
这将为您带来以下好处:
- 减少对strlen的冗余调用。每个调用都必须遍历字符串,因此最好尽量减少这些调用
- 第二个
memcpy
需要实际附加,而不是替换。因此,第一个参数必须与前一个调用不同
- 注意第二个
memcpy
的第三个参数中的+1
。那是给NUL终结者的
我不确定你的if
声明是否有意义。也许更明智的做法是确保g->db\u cmd
有足够的空间来复制您要复制的内容。您可以通过sizeof
(如果db\u cmd
是一个字符数组)或跟踪堆分配的大小(如果db\u cmd
是通过malloc
获取的)。因此,也许最有意义的是:
size_t param_value_len = strlen(l->db.param_value.val),
del_const_len = strlen(l->del_const);
// Assumption is that db_cmd is a char array and hence sizeof(db_cmd) makes sense.
// If db_cmd is a heap allocation, replace the sizeof() with how many bytes you
// asked malloc for.
//
if (param_value_len + del_const_len < sizeof(g->db_cmd))
{
memcpy(g->db_cmd, l->db.param_value.val, param_value_len);
memcpy(g->db_cmd + param_value_len, l->del_const, del_const_len + 1);
}
else
{
// TODO: your buffer is not big enough. handle that.
}
size\t param\u value\u len=strlen(l->db.param\u value.val),
del_const_len=strlen(l->del_const);
//假设db_cmd是一个字符数组,因此sizeof(db_cmd)是有意义的。
//如果db_cmd是一个堆分配,则将sizeof()替换为您需要的字节数
//向马洛克索要。
//
if(参数值+del_const_lendb_cmd))
{
memcpy(g->db_cmd,l->db.param_value.val,param_value_len);
memcpy(g->db_cmd+param_value_len,l->del_const,del_const_len+1);
}
其他的
{
//TODO:您的缓冲区不够大。请处理这个问题。
}
FYI:C允许将长语句拆分为多行,甚至可以拆分为多个带有额外变量的语句来保存中间结果。我要注意的是,一些嵌入式数据库(我认为berkeley DB)明确使用数据和长度。数据不需要以null结尾,并且可能包含null。在这种情况下,如果您的程序已经从DB API获得了长度,请保留该长度,并避免使用strlen。
size_t orig_len = strlen(g->db_cmd);
size_t result = strlcat( g->db_cmd, l->db.param_value.val, sizeof(g->db_cmd));
result = strlcat( g->db_cmd, l->del_const, sizeof(g->db_cmd));
g->cmd_ctr++;
if (result >= sizeof(g->db_cmd)) {
// the new stuff didn't fit, 'roll back' to what we started with
g->db_cmd[orig_len] = '\0';
g->cmd_ctr--;
}
size_t len = strlen(l->db.param_value.val);
memcpy(g->db_cmd, l->db.param_value.val, len);
memcpy(g->db_cmd + len, l->del_const, strlen(l->del_cost)+1);
size_t param_value_len = strlen(l->db.param_value.val),
del_const_len = strlen(l->del_const);
// Assumption is that db_cmd is a char array and hence sizeof(db_cmd) makes sense.
// If db_cmd is a heap allocation, replace the sizeof() with how many bytes you
// asked malloc for.
//
if (param_value_len + del_const_len < sizeof(g->db_cmd))
{
memcpy(g->db_cmd, l->db.param_value.val, param_value_len);
memcpy(g->db_cmd + param_value_len, l->del_const, del_const_len + 1);
}
else
{
// TODO: your buffer is not big enough. handle that.
}