在C ++中将字符序列重复到更大缓冲区的最简单方法

时间:2009-03-12 21:17:25

标签: c++ stl boost

给定(在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复制到buffer N次的最简单方法吗? STL / BOOST中有什么东西可以做这样的事吗?

例如,如果序列为“abcd”,而N为3,则buffer最终将包含“abcdabcdabcd”。

4 个答案:

答案 0 :(得分:12)

我可能会这样做:

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

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

如果你想要这些是c字符串,你必须分配一个额外的字节并在'\0'中添加一个结尾。给定一个c字符串和一个整数,你想这样做:

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

答案 1 :(得分:7)

重复缓冲区,同时避免指针运算:

你可以使用std :: vector&lt; char&gt;或者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;

答案 2 :(得分:4)

您可以使用STL算法生成:

MSDN: Generate

答案 3 :(得分:3)

如果已知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的所有约束并且还替换了有一段时间的奇怪陈述。

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