2011-11-24 81 views
1

我试图使用memcpy函数连接一个字符,但是,在memcpy之后,我得到了一个奇怪的缓冲区长度。请参阅下面在C++ memcpy后得到strlen

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的仍然是零?

回答

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 
2

您应该不会strlen目的地memcpy ing strlen字节从原来的,因为您没有复制0终止符。

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

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; 
} 
0

有多个问题在这里。

首先使用& uibuffer作为参数传递给memcpy的是错的,只是用uibuffer (rxbuffer,l),因为他们已经是一个地址(即数组):

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

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