1

我正在尝试使用 memcpy 函数连接一个字符,但是,在几个 memcpy 之后,我的缓冲区长度有点奇怪。请看下面的代码

int main()
{
uint8 txbuffer[13]={0};
uint8 uibuffer[4] = "abc";
uint8 rxbuffer[4] = "def";
uint8 l[2]="g";
int index = 1;

cout << strlen((char*)txbuffer) <<endl;
memcpy(&txbuffer[1],&uibuffer, strlen((char*)uibuffer));
index+=strlen((char*)uibuffer);

cout <<"after first memcpy: "<< strlen((char*)txbuffer) <<endl;
memcpy(&txbuffer[index],&rxbuffer, strlen((char*)uibuffer));

cout <<"after second memcpy: "<< strlen((char*)txbuffer) <<endl;
memcpy(&txbuffer[0],&l, strlen((char*)l));

cout <<"after third memcpy: "<< strlen((char*)txbuffer) <<endl;
for (int i = 0; i < sizeof(txbuffer); i += 1)
{
    cout << (int(txbuffer[i]))<<" : "<< char(int(txbuffer[i]))<<endl;
}
return 0;
}

输出是:

after first memcpy: 0
after second memcpy: 0
after third memcpy: 7
103 : g
97 : a
98 : b
99 : c
100 : d
101 : e
102 : f
0 : 
0 : 
0 : 
0 : 
0 : 
0 :

我的问题是为什么在第一个 memcpy 之后,缓冲区的 strlen 仍然为零?

4

4 回答 4

2

您不应该在ing原始字节strlen之后进行目的地,因为您没有复制 0 终止符。memcpystrlen

此外,您从字节 1 开始复制,而不是 0,意思strlen是 0,因为您的数组最初是零(这使我的第一段无关紧要,但您应该注意这一点)。

于 2011-11-24T21:00:33.430 回答
1

这是因为第一个字符txbuffer是空字符\0。(您以这种方式对其进行了初始化。)因此,当您将字符串打印出来时,它实际上具有零长度。

您没有覆盖第一个或第二个副本中的第一个字符。但是你最终在第三个副本中覆盖了它。这就是为什么在第三个副本之后长度为零的原因。

//  Start
{  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0}

//  After 1st memcpy(): strlen() is still zero
{  0, 'a', 'b', 'c',   0,   0,   0,   0,   0,   0,   0,   0,   0}
   ^ first null character

//  After 2nd memcpy(): strlen() is still zero
{  0, 'a', 'b', 'c', 'd', 'e', 'f',   0,   0,   0,   0,   0,   0}
   ^ first null character

//  After 3rd memcpy(): strlen() is now 7
{'g', 'a', 'b', 'c', 'd', 'e', 'f',   0,   0,   0,   0,   0,   0}
                                      ^ first null character
于 2011-11-24T21:00:35.080 回答
0

这里有多个问题。

首先使用 &uibuffer 作为 memcpy 的参数是错误的,只需使用它们,uibuffer (rxbuffer,l)因为它们已经是一个地址(作为数组):

memcpy(&txbuffer[1], uibuffer, strlen((char*)uibuffer));

在上面的 txbuffer 上做一个 strlen(因为你复制到带有偏移量 1 的 txtbuffer)将产生 0 长度,因为 strlen 计数直到它找到 \0,将 strlen 与 memcpy 结合使用不是一个好主意,而是跟踪你的长度手动在 txtbuffer 中,你知道你复制的字符串的长度和偏移量。

于 2011-11-24T21:11:01.860 回答
0

strlen()计算非 NUL 字节数。由于初始 NUL 在复制后仍然存在,因此当然strlen()返回零。

相反,您可能更喜欢使用sizeof或更明确的串联逻辑:

int main()
{
    char txbuffer[13];
    char uibuffer[4] = "abc";
    char rxbuffer[4] = "def";
    char l[2]="g";
    int index = 1;

    int n = sprintf (txbuffer, "%s%s%s", uibuffer, rxbuffer, l);
    cout << "buffer has " << n << " bytes" << endl;
    return 0;
}
于 2011-11-24T21:00:39.860 回答