无法使用memcpy从缓冲区中删除特定字节
我无法根据需要的大小截断缓冲区。我有点困惑为什么我会得到错误的结果?尽管我对memcpy()的使用是正确的。我也读了手册页。我做错什么了无法使用memcpy从缓冲区中删除特定字节,c,memory,C,Memory,我无法根据需要的大小截断缓冲区。我有点困惑为什么我会得到错误的结果?尽管我对memcpy()的使用是正确的。我也读了手册页。我做错什么了 我想要实现的目标: Buff: 00 83 00 00 16 0a 44 00 00 00 00 bd 0e 8a 0c 61 01 13 51 24 ad 9a 0b 1c 0e ff ff 00 * 01 00 83 00 00 16 0a 44 00 00 00 00 bd 0e 8a 0c 61 01 13 51 24 ad 9a 0b 1c 0e
我想要实现的目标:
Buff: 00 83 00 00 16 0a 44 00 00 00 00 bd 0e 8a 0c 61 01 13 51 24 ad 9a 0b 1c 0e ff ff 00
* 01 00 83 00 00 16 0a 44 00 00 00 00 bd 0e 8a 0c 61 01 13 51 24 ad 9a 0b 1c 0e ff ff 00
p* 00 83 00 00 16 0a 44 00 00 00 00 bd 0e 8a 0c 61 01 13 51 24 ad 9a 0b 1c 0e ff ff 00
复制从bd开始的字节,也就是说从第12个字节一直复制到最后-
所需输出应为:
bd 0e 8a 0c 61 01 13 51 24 ad 9a 0b 1c 0e ff 00
这是我的代码:
我正在接收来自串行设备的响应,我需要切掉一些字节
void rx_dev(transport, int addr, const void *buf, unsigned count) {
uint8_t s[1024];
uint8_t *p;
memset (s, 0, sizeof(s));
// This below function does only the hex parsing.
hex_parse(s, sizeof(s), buf, count);
printf("* %02x %s\n", addr, s);
printf("Count: %zu\n", count);
p = s;
printf("p* %s\n", p);
// I'm doing this check to avoid something greater than 14.
if (count > 14) {
memcpy(p, s+11, count-11);
printf("*Trim:%s\n", p);
}
}
编辑:添加更多详细信息
int hex_parse(char *out, unsigned size, const void *buf, unsigned count)
{
const uint8_t *p = buf;
unsigned i;
int n = 0;
if (count)
{
if (n + 2 < size)
{
out[n+0] = hexchars[(p[0] >> 4) & 15];
out[n+1] = hexchars[p[0] & 15];
}
n += 2;
}
for (i = 1; i < count; i++) {
if (n + 3 < size)
{
out[n+0] = ' ';
out[n+1] = hexchars[(p[i] >> 4) & 15];
out[n+2] = hexchars[p[i] & 15];
}
n += 3;
}
if (n < size)
out[n] = '\0';
else if (size)
out[size-1] = '\0';
return n;
}
在这里我没有得到正确的输出,为什么它是普林28字节,这不是我想要的结果
Trim: 16 0a 44 00 00 0 44 00 00 00 00 bd 0e 8a 0c 61 01 13 51 24 ad 9a 0b 1c 0e ff ff 00
调用
memcpy
时,没有从缓冲区复制字节。您正在复制“hex_parsed”字符串。由于该格式每字节使用3个字符(2位数字和一个空格),因此截断11个字符等于截断大约4个字节。当您调用memcpy
时,您没有从缓冲区复制字节。您正在复制“hex_parsed”字符串。由于该格式每字节使用3个字符(2个数字和一个空格),因此截断11个字符等于截断大约4个字节。您可以使用memmove
,就像在memcpy
中一样,目标和源不能相互重叠,而在memmove中则无关紧要。所以你可以
int offset = 11,size = 28;
memmove(buf, buf+off, size - off);
您可以使用
memmove
,就像在memcpy
中一样,目标和源不能相互重叠,而在memmove中则无关紧要。所以你可以
int offset = 11,size = 28;
memmove(buf, buf+off, size - off);
memcpy
调用中的源和目标重叠。根据标准:
如果复制发生在重叠的对象之间,则该行为
没有定义
标准函数
memmove
类似于memcpy
,但定义为重叠对象,请改用它。调用memcpy
中的源和目标。根据标准:
如果复制发生在重叠的对象之间,则该行为
没有定义
标准函数
memmove
类似于memcpy
,但定义为重叠对象,请使用它。我认为我们需要查看hex\u parse
才能完全理解这一点。但是,如果要将缓冲区转换为十六进制字符串,为什么要先修剪十六进制字符串而不是缓冲区。@mttrb我还添加了十六进制解析函数实现。我认为我们需要查看hex_parse
,才能完全理解这一点。但是,如果要将缓冲区转换为十六进制字符串,为什么要先修剪十六进制字符串而不是缓冲区。@mttrb我还添加了hex_解析函数实现。谢谢您指出。您的正确格式化每个字节使用3个字符。在我的例子中,我想从第12字节复制,然后11*3=33。但是count给了我28,我只想打印到最后。@DanglingPointercount
也有同样的问题。它计算缓冲区中的字节,而不是解析的字符串中的字符代码>其中rx为uint8_t rx[1024];但是,即使在使用memmove之后,我也没有得到正确的答案。@DanglingPointer:您的代码有多个问题(字节和字符混合,源代码和目标代码重叠),您需要解决所有问题谢谢您的指出。因为这就是我的印象,代码有多个问题,我没有正确的src,这就是为什么我的目标得到错误的值。我会弄明白的。谢谢你指出。您的正确格式化每个字节使用3个字符。在我的例子中,我想从第12字节复制,然后11*3=33。但是count给了我28,我只想打印到最后。@DanglingPointercount
也有同样的问题。它计算缓冲区中的字节,而不是解析的字符串中的字符代码>其中rx为uint8_t rx[1024];但是,即使在使用memmove之后,我也没有得到正确的答案。@DanglingPointer:您的代码有多个问题(字节和字符混合,源代码和目标代码重叠),您需要解决所有问题谢谢您的指出。因为这就是我的印象,代码有多个问题,我没有正确的src,这就是为什么我的目标得到错误的值。我会弄明白的。如何避免重叠,我是否可以不使用另一个指针作为目标?@DanglingPointer您可以复制到另一个缓冲区。我试图复制到另一个缓冲区,我只是得到了垃圾值<代码>memmove(接收,buf+11,计数-11)代码>和rx为uint8_t rx[1024]似乎我在这里犯了一些错误。你能告诉我为什么吗?这里buf是无效指针。如何避免重叠,是否可能我不能将另一个指针作为目标?@DanglingPointer您可以复制到其他缓冲区。我试图复制到其他缓冲区,我只是得到了垃圾值<代码>memmove(接收,buf+11,计数-11)代码>和rx为uint8_t rx[1024]似乎我在这里犯了一些错误。你能告诉我为什么吗?这里buf是空指针。@alinsor,我使用了memove,尽管这没有帮助。Buf是void指针,我在这里向void指针添加+11。我似乎没有移动特定缓冲区中的字节。它只是打印垃圾值。memmove必须工作。您现在应该在代码中使用幻数,但我使用它们只是为了提供一个使用示例。@alinsor,我使用了memove,尽管这没有帮助。Buf是void指针,我在这里向void指针添加+11。我似乎没有移动特定缓冲区中的字节。它只是打印垃圾值。memmove必须工作。您现在应该在代码中使用幻数,但我使用它们只是为了提供一个使用示例。