我希望从指定起始点将特定长度的内容从一个缓冲区复制到另一个缓冲区。我查看了memcpy()
,但它仅接受要复制的内容长度,而我想要指定起始索引。
是否有任何函数可以执行此操作,或者是否有任何好的方法可以使用现有的memcpy
函数进行操作?
我总是更喜欢这种语法
memcpy( &dst[dstIdx], &src[srcIdx], numElementsToCopy * sizeof( Element ) );
只需将您想要的偏移量添加到缓冲区的地址即可。
char abuff[100], bbuff[100];
....
memcpy( bbuff, abuff + 5, 10 );
这个程序会将从abuff[5]开始的10个字节复制到bbuff中。
只需要将偏移量加到地址上即可。例如,如果您想复制从第N个字节开始的缓冲区:
memcpy( destination, source + N, sourceLen - N );
这将复制到destination
。如果你还想偏移目标位置-在两个位置都加上偏移量:
memcpy( destination + N, source + N, sourceLen - N );
不需要索引,因为您可以通过指定的字节数简单地更新源指针。以下包装器应该能解决问题。
void* memcpy_index(void *s1, const void *s2, size_t index, size_t n) {
s2 = ((char*)s2)+index;
return memcpy(s1, s2,n);
}
只需将指针增加到起始索引。
示例
const unsigned char * src = reinterpret_cast<const unsigned char*>(your source);
unsigned char * dest = reinterpret_cast<unsigned char *>(your dest);
memcpy(dest, src + offset, len);
这个网站需要一种方法,允许匿名回复,除了匿名答案。
为什么我会看到这种疯狂的说法,认为“索引”必须以1字节为单位?这完全与惯例相反。“索引”通常是象征性的,其物理字节偏移量由数组中元素的大小确定(或向量,可能甚至没有数组的物理布局,但是memcpy()当然也无关紧要)。
因此,数组中的第5个元素具有“索引”5,但:
哪种方式是访问特定元素的正确方式是一个次要问题。重要的是您理解差异,选择一种并使代码正确。
在词义方面,我更愿意阅读:
void* memcpy_offset(void *s1, const void *s2, size_t offset, size_t n);
比:
void* memcpy_index(void *s1, const void *s2, size_t index, size_t n);
我认为一个完全通用的void *可以有一个“索引”的想法是具有误导性的。(顺便说一下,“dest”和“source”或“in”和“out”比“s1”和“s2”不太含糊。当您选择自说明的变量名称时,代码不需要太多注释。)
template<typename T>
T* memcopy_index(T* dst,T* src,unsigned int index, unsigned int element_count)
{
return (T*)memcpy(dst,src + index, element_count * sizeof(T));
}
它可以如下使用:
int src[]={0,1,2,3,4,5,6};
int dst[15];
memcopy_index(dst,src,2,5); //copy 5 elements from index 2
你必须确保目标缓冲区有足够的空间来复制元素。
int src[20];
int dst[15];
// Copy last 10 elements of src[] to first 10 elements of dst[]
std::copy( src+10, src+20, dst );
与memcpy()一样,您有责任确保指针是有效的。
注意。如果您的使用对性能至关重要,您可能会发现在其他答案中详细介绍的memcpy()更快,但差别可能不大。
只需将索引添加到缓冲区的地址中,并将其作为源参数传递给memcpy()
,例如从缓冲区b的第3个项目复制
char a[10], b[20];
::memcpy(a,b+2,10);
还要考虑缓冲区中项目的类型,memcpy()的长度(第三个)参数以字节为单位,因此要复制4个int,您应该放置4*sizeof(int) - 这可能是16(在32位系统上)。但是对于起始地址,类型并不重要,因为指针算术:
int a[10], b[10];
::memcpy( a+2, b, 2*sizeof(int) );
// a+2 will be address of 3rd item in buffer a
// not address of 1st item + 2 bytes
memcpy
函数。但是,C++ 本身提供了std::copy
函数,通常情况下它与memcpy
相当甚至更好,并且更加灵活和类型安全。 - underscore_d