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'
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'
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.
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.
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).
You should write your own stream manipulator
cout << multi(5) << "whatever" << "lolcat";
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;
}
@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.
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.