在c ++中使用memcpy后得到strlen

时间:2011-11-24 20:58:26

标签: c++ memcpy strlen

我试图使用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 个答案:

答案 0 :(得分:2)

在原始strlenmemcpy个字节之后,您不应该strlen目的地,因为您没有复制0终结符。

此外,你从字节1开始复制,而不是0,意味着strlen为0,因为你的数组最初被归零(这种情况使我的第一段无关紧要,但你应该知道它)。 / p>

答案 1 :(得分:1)

这是因为txbuffer中的第一个字符是空字符\0。 (你用这种方式初始化它。)因此,当你打印出来时,字符串有效地具有零长度。

您没有覆盖第一个或第二个副本中的第一个字符。但是你最终会在第3份副本中覆盖它。这就是为什么长度为零,直到第三次复制之后。

//  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

答案 2 :(得分: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;
}

答案 3 :(得分:0)

这里有很多问题。

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

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

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