How can I repeat a string a variable number of times in C++?

C++

C++ Problem Overview


I want to insert 'n' spaces (or any string) at the beginning of a string in C++. Is there a direct way to do this using either std::strings or char* strings?

E.g., in Python you could simply do

>>> "." * 5 + "lolcat"
'.....lolcat'

C++ Solutions


Solution 1 - C++

In the particular case of repeating a single character, you can use std::string(size_type count, CharT ch):

std::string(5, '.') + "lolcat"

This can't be used to repeat multi-character strings.

Solution 2 - C++

There's no direct idiomatic way to repeat strings in C++ equivalent to the * operator in Python or the x operator in Perl. If you're repeating a single character, the two-argument constructor (as suggested by previous answers) works well:

std::string(5, '.')

This is a contrived example of how you might use an ostringstream to repeat a string n times:

#include <sstream>

std::string repeat(int n) {
    std::ostringstream os;
    for(int i = 0; i < n; i++)
        os << "repeat";
    return os.str();
}

Depending on the implementation, this may be slightly more efficient than simply concatenating the string n times.

Solution 3 - C++

Use one of the forms of string::insert:

std::string str("lolcat");
str.insert(0, 5, '.');

This will insert "....." (five dots) at the start of the string (position 0).

Solution 4 - C++

I know this is an old question, but I was looking to do the same thing and have found what I think is a simpler solution. It appears that cout has this function built in with cout.fill(), see the link for a 'full' explanation

http://www.java-samples.com/showtutorial.php?tutorialid=458

cout.width(11);
cout.fill('.');
cout << "lolcat" << endl;

outputs

.....lolcat

Solution 5 - C++

For the purposes of the example provided by the OP std::string's ctor is sufficient: std::string(5, '.'). However, if anybody is looking for a function to repeat std::string multiple times:

std::string repeat(const std::string& input, unsigned num)
{
    std::string ret;
    ret.reserve(input.size() * num);
    while (num--)
        ret += input;
    return ret;
}

Solution 6 - C++

As Commodore Jaeger alluded to, I don't think any of the other answers actually answer this question; the question asks how to repeat a string, not a character.

While the answer given by Commodore is correct, it is quite inefficient. Here is a faster implementation, the idea is to minimise copying operations and memory allocations by first exponentially growing the string:

#include <string>
#include <cstddef>

std::string repeat(std::string str, const std::size_t n)
{
    if (n == 0) {
        str.clear();
        str.shrink_to_fit();
        return str;
    } else if (n == 1 || str.empty()) {
        return str;
    }
    const auto period = str.size();
    if (period == 1) {
        str.append(n - 1, str.front());
        return str;
    }
    str.reserve(period * n);
    std::size_t m {2};
    for (; m < n; m *= 2) str += str;
    str.append(str.c_str(), (n - (m / 2)) * period);
    return str;
}

We can also define an operator* to get something closer to the Python version:

#include <utility>
    
std::string operator*(std::string str, std::size_t n)
{
    return repeat(std::move(str), n);
}

On my machine this is around 10x faster than the implementation given by Commodore, and about 2x faster than a naive 'append n - 1 times' solution.

Solution 7 - C++

You should write your own stream manipulator

cout << multi(5) << "whatever" << "lolcat";

Solution 8 - C++

You can use a C++ function for doing this:

 std::string repeat(const std::string& input, size_t num)
 {
    std::ostringstream os;
    std::fill_n(std::ostream_iterator<std::string>(os), num, input);
    return os.str();
 }

Solution 9 - C++

Here's an example of the string "abc" repeated 3 times:

#include <iostream>
#include <sstream>
#include <algorithm>
#include <string>
#include <iterator>

using namespace std;

int main() {
    ostringstream repeated;
    fill_n(ostream_iterator<string>(repeated), 3, string("abc"));
    cout << "repeated: " << repeated.str() << endl;  // repeated: abcabcabc
    return 0;
}

Solution 10 - C++

@Daniel provided an implementation that is significantly faster than other answers in its primary execution branch (where n > 1 and str is not empty). However, the corner cases are handled much more inefficiently than they could be.

This implementation corrects those issues:

#include <string>
#include <cstddef>

std::string repeat(size_t n, const std::string& str) {
    if (n == 0 || str.empty()) return {};
    if (n == 1) return str;
    const auto period = str.size();
    if (period == 1) return std::string(n, str.front());

    std::string ret(str);
    ret.reserve(period * n);
    std::size_t m {2};
    for (; m < n; m *= 2) ret += ret;
    ret.append(ret.c_str(), (n - (m / 2)) * period);
    return ret;
}

A benchmark comparison of the two implementations on quick-bench.com shows the following differences in these corner cases. Clang 13.0 is the first number and GCC 10.3 is the second. -O3 optimization in all cases.

  • For n == 0, this implementation is (9x / 11x) faster.
  • For str.empty() == true, it is (2.4x / 3.4x) faster.
  • For n == 1 and str.size() > 1, it is (2.1x / 1.4x) faster.
  • And for str.size() == 1, it is (1.3x / 1.2x) faster.

The problem with the original implementation boils down to passing str into the function by value. This invokes a copy of str on every call to repeat that is unnecessary in some of the corner cases; especially when n == 0.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionMarcusView Question on Stackoverflow
Solution 1 - C++lukeView Answer on Stackoverflow
Solution 2 - C++Commodore JaegerView Answer on Stackoverflow
Solution 3 - C++camhView Answer on Stackoverflow
Solution 4 - C++IanView Answer on Stackoverflow
Solution 5 - C++Pavel PView Answer on Stackoverflow
Solution 6 - C++DanielView Answer on Stackoverflow
Solution 7 - C++RoskotoView Answer on Stackoverflow
Solution 8 - C++sorosh_sabzView Answer on Stackoverflow
Solution 9 - C++claytonjwongView Answer on Stackoverflow
Solution 10 - C++Matthew M.View Answer on Stackoverflow