-1

Question:

in C++ : Given the std::string s = "copyme" how can I make a string b which is "copymecopymecopyme" or any generalized s + s + ... n times?


possible solutions

A possible solution would be a method/macro that does a for loop, but that would be horribly inefficient.

What is an efficient method of doing this string copy operation, e.g. as the previous author says in the style of 'string'*n in python or ruby.

a relatively efficient loop would be allocating strlen*n and then copying the chars over multiple times rather than for(...) {str+=copy_this_string;} which does multiple copies and allocates.

another solution is using a stringbuffer.


SO clarifications

key: without using a macro. clarification: the 'char array' in the question is because in the original question, due to a single char in the string, all answers ignored the copying of a general stream and focused on using '.' since it had easily accessible methods such as the stream constructor.

"Duplicate" : How to repeat a string a variable number of times in C++? Except most the answers all used methods that only had a char repeated, e.g. the String Constructor and insert methods, which did not answer the original question and were unhelpful when I then looked for an efficient method.

Community
  • 1
  • 1

2 Answers2

3

If you're worried about the string '+=' operation being inefficient, one optimization you can make is to reserve memory in the target string container. This may avoid inefficient re-allocations of memory.
For example:

std::string s = "copyme";
std::string b;
target.reserve(s.length()*5);
for (int index = 0; index < 5; ++index)
{
    b += s;
}

I checked the std::string implementation on my linux system and it appears this method will not cause re-allocation of the array as long as the initial reservation is large enough.

template<typename _CharT, typename _Traits, typename _Alloc>
basic_string<_CharT, _Traits, _Alloc>&
basic_string<_CharT, _Traits, _Alloc>::
append(const basic_string& __str)
{
    const size_type __size = __str.size();
    if (__size)
    {
        const size_type __len = __size + this->size();
        if (__len > this->capacity() || _M_rep()->_M_is_shared())
            this->reserve(__len);
        _M_copy(_M_data() + this->size(), __str._M_data(), __size);
        _M_rep()->_M_set_length_and_sharable(__len);
    }
    return *this;
}    
KyleL
  • 1,379
  • 2
  • 13
  • 35
  • used for copying into it rather than copying from it. but yes this is more efficient as it reduces allocations +1. –  Jun 28 '13 at 17:29
1

A simple loop would do. If you are concerned about re-allocations, you can call std::string::reserve on the copy string:

#include <string>
#include <iostream>

int main()
{
  const int num + 5;
  std::string s = "copyme";
  std::string b;
  b.reserve(s.size() * num); // reserve space for num* "copyme"
  for (int i = 0; i < num; ++i) b += s;

  std::cout << b << std::endl;
}
juanchopanza
  • 223,364
  • 34
  • 402
  • 480