在C++中将一系列字节重复到较大缓冲区的最简单方法

7

给定(使用C ++)

char * byte_sequence;
size_t byte_sequence_length;
char * buffer;
size_t N;

假设byte_sequencebyte_sequence_length被初始化为一些任意长度的字节序列(及其长度),而buffer被初始化为指向N * byte_sequence_length字节,那么最简单的方法是将byte_sequence复制到bufferN次。STL / BOOST中是否有已经执行此类操作的函数?
例如,如果序列为“abcd”,并且N为3,则buffer将包含“abcdabcdabcd”。
4个回答

12

我可能会选择这个:

for (int i=0; i < N; ++i)
    memcpy(buffer + i * byte_sequence_length, byte_sequence, byte_sequence_length);

假设你正在处理二进制数据并跟踪长度,而不是使用'\0'终止符。

如果你想要它们成为c-strings,你需要分配一个额外的字节,并在末尾添加'\0'。给出一个c-string和一个整数,您可以像这样完成:

char *RepeatN(char *source, size_t n)
{
    assert(n >= 0 && source != NULL);            
    size_t length = strlen(source) - 1;
    char *buffer = new char[length*n + 1];
    for (int i=0; i < n; ++i)
        memcpy(buffer + i * length, source, length);
    buffer[n * length] = '\0';
}

7

重复缓冲区而避免指针算术:

您可以使用std::vector<char>或std::string来使事情更容易。这两个容器也可以保存二进制数据。

此解决方案具有以下良好特性:

  • 您不需要担心内存访问违规
  • 您不需要担心获取正确的缓冲区大小
  • 您可以随时将序列附加到您的缓冲区,而无需手动重新分配

.

//Note this works even for binary data.
void appendSequenceToMyBuffer(std::string &sBuffer
       , const char *byte_sequence
       , int byte_sequence_length
       , int N)
{
  for(int i = 0; i < N; ++i)
      sBuffer.append(byte_sequence, byte_sequence_length);
}

//Note: buffer == sBuffer.c_str()

备选方案:使用memcpy处理二进制数据:

buffer = new char[byte_sequence_length*N];
for (int i=0; i < N; ++i)
  memcpy(buffer+i*byte_sequence_length, byte_sequence, byte_sequence_length); 
//...
delete[] buffer;

替代方法:对于使用strcpy的空终止字符串数据:

buffer = new char[byte_sequence_length*N+1];
int byte_sequence_length = strlen(byte_sequence);
for (int i=0; i < N; ++i)
  strcpy(buffer+i*byte_sequence_length, byte_sequence, byte_sequence_length); 
//...
delete[] buffer;

替代方案:如果您要使用单个值填充缓冲区:

buffer = new char[N];
memset(buffer, byte_value, N);
//...
delete[] buffer;

对于第一个解决方案,有一个建议 - 如果在执行附加操作之前调用sBuffer.reserve(byte_sequence_length*N),则可以防止多次重新分配。 - Eclipse

4

如果N是2的幂次方,则可以从缓冲区的第一部分复制到后续部分,每次增加复制量:

assert((N > 0) && ((N & (N-1)) == 0));
memcpy(buffer, byte_sequence, byte_sequence_length);
for (size_t i = 1;  i < N;  i *= 2)
    memcpy(buffer + i * byte_sequence_length, buffer, i * byte_sequence_length);
编辑:将此扩展到N 不是 2的幂次方很容易。这里有一个改进的版本,它消除了对N的所有限制,并用while替换了奇数for语句。
if (N > 0)
    memcpy(buffer, byte_sequence, byte_sequence_length);
size_t copied = 1;
while (copied < N)
{
    size_t tocopy = min(copied, N - copied);
    memcpy(buffer + copied * byte_sequence_length, buffer, tocopy * byte_sequence_length);
    copied += tocopy;
}

4

谢谢!已更新。 - mwigdahl

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接