How to repeat a string a variable number of times in C++?C++ equivalent of Python '#'*number?Porting Perl to C++ `print “x2501” x 12;`What setup does REP do?Apache Thrift : difference between byte and binary typesstring Multiplication in C++Prefix vs infix operator* with string literalsHow to copy a char array / String a variable number of times C++What are the differences between a pointer variable and a reference variable in C++?Remove spaces from std::string in C++How do I iterate over the words of a string?How can I profile C++ code running on Linux?Static constant string (class member)Easiest way to convert int to string in C++C++11 introduced a standardized memory model. What does it mean? And how is it going to affect C++ programming?Why should C++ programmers minimize use of 'new'?Why is reading lines from stdin much slower in C++ than Python?Image Processing: Algorithm Improvement for 'Coca-Cola Can' Recognition
Book about a new laser rifle built by a new inventor
Why doesn't SpaceX land boosters in Africa?
Variable declaration inside main loop
Does "boire un jus" tend to mean "coffee" or "juice of fruit"?
Installed software from source, how to say yum not to install it from package?
How can solar sailed ships be protected from space debris?
Tricky riddle from sister
Why can't i use !(single pattern) in zsh even after i turn on kshglob?
Where to connect the fuse and why?
What prevents a US state from colonizing a smaller state?
Old story where computer expert digitally animates The Lord of the Rings
Is a ccH, ccX and ccH equivalent to a cH, ccX and cH sequence?
What verb goes with "coup"?
Does friction always oppose motion?
Which are more efficient in putting out wildfires: planes or helicopters?
Does Dhp 256-257 condone judging others?
German idiomatic equivalents of 能骗就骗 (if you can cheat, then cheat)
How to idiomatically express the idea "if you can cheat without being caught, do it"
What does this Pokemon Trainer mean by saying the player is "SHELLOS"?
What's the idiomatic (or best) way to trim surrounding whitespace from a string?
What caused the flashes in the video footage of Chernobyl?
Why will we fail creating a self sustaining off world colony?
Simplify the code
What could a Medieval society do with excess animal blood?
How to repeat a string a variable number of times in C++?
C++ equivalent of Python '#'*number?Porting Perl to C++ `print “x2501” x 12;`What setup does REP do?Apache Thrift : difference between byte and binary typesstring Multiplication in C++Prefix vs infix operator* with string literalsHow to copy a char array / String a variable number of times C++What are the differences between a pointer variable and a reference variable in C++?Remove spaces from std::string in C++How do I iterate over the words of a string?How can I profile C++ code running on Linux?Static constant string (class member)Easiest way to convert int to string in C++C++11 introduced a standardized memory model. What does it mean? And how is it going to affect C++ programming?Why should C++ programmers minimize use of 'new'?Why is reading lines from stdin much slower in C++ than Python?Image Processing: Algorithm Improvement for 'Coca-Cola Can' Recognition
I want to insert 'n' spaces (or any string) at the beginning of a string in C++. Is there any direct way to do this using either std::strings or char* strings?
E.g. in Python you could simply do
>>> "." * 5 + "lolcat"
'.....lolcat'
c++
add a comment |
I want to insert 'n' spaces (or any string) at the beginning of a string in C++. Is there any direct way to do this using either std::strings or char* strings?
E.g. in Python you could simply do
>>> "." * 5 + "lolcat"
'.....lolcat'
c++
Someone provide an answer using QString?
– Akiva
Dec 12 '15 at 17:46
add a comment |
I want to insert 'n' spaces (or any string) at the beginning of a string in C++. Is there any direct way to do this using either std::strings or char* strings?
E.g. in Python you could simply do
>>> "." * 5 + "lolcat"
'.....lolcat'
c++
I want to insert 'n' spaces (or any string) at the beginning of a string in C++. Is there any direct way to do this using either std::strings or char* strings?
E.g. in Python you could simply do
>>> "." * 5 + "lolcat"
'.....lolcat'
c++
c++
asked Oct 3 '08 at 12:43
Marcus
Someone provide an answer using QString?
– Akiva
Dec 12 '15 at 17:46
add a comment |
Someone provide an answer using QString?
– Akiva
Dec 12 '15 at 17:46
Someone provide an answer using QString?
– Akiva
Dec 12 '15 at 17:46
Someone provide an answer using QString?
– Akiva
Dec 12 '15 at 17:46
add a comment |
8 Answers
8
active
oldest
votes
In the particular case of repeating a single character, you can use std::string(size_type count, CharT ch):
std::string(5, '.') + "lolcat"
NB. This can't be used to repeat multi-character strings.
61
The OP asked for repeating a string, not a character.
– Florian Kaufmann
Jan 20 '16 at 21:10
add a comment |
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.
add a comment |
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).
10
The OP asked for repeating a string, not a character.
– Brent
Dec 29 '17 at 19:45
@Brent The OP asked for both - "'n' spaces (or any string)", and then goes on to demonstrate their intent with a single period as the string. English is not many people's first language so you sometimes need to guess their exact requirements and when analysed, the question is really asking how to do this with a single character. I'm sorry you found my answer unhelpful enough you needed to down vote it.
– camh
Dec 30 '17 at 7:10
add a comment |
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
1
This won't work if all you want is the dots.
– uckelman
Oct 28 '11 at 15:40
5
only dots: change last line to...cout << "" << endl;
– musefan
Jan 11 '12 at 11:11
add a comment |
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)
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.
Your implementation does not 'minimize copying'. Mind that the+=within your for loop internally also has a loop of some sort which doesstr.size()iterations.str.size()grows in each outer loop iteration, so after each outer iteration the inner loop has to do more iterations. Your and the naive 'copy n times' implementation in total both copyn * periodcharacters. Your implementation does only one memory allocation because of the initialreserve. I guess you profiled your implementation with a rather smallstrand a bign, but not also with bigstrand a smalln.
– Florian Kaufmann
Jan 20 '16 at 21:02
@FlorianKaufmann Not sure why you've chosen to attack my answer. But by "minimise copying" I mean 'copying operations'. The idea being that copying a small number of big blocks is more efficient (for a variety of reasons) than copying a large number of small blocks. I potentially avoid an additional allocation on the input string over the naive method.
– Daniel
Jan 20 '16 at 23:57
1
It was a comment stating that I don't believe your claim that your solution is much better in terms of efficiency than the naive solution. In my measurements, compared to the naive solution, your code is faster with small strings and many repetitions, but slower with long strings and few repetitions. Could you provide links explaining in more detail the variety of reasons why copying a few big blocks has a higher performance than copying many small blocks? I can think of branch prediction. Regarding CPU cache I am unsure which variant is preferred.
– Florian Kaufmann
Jan 21 '16 at 7:42
@FlorianKaufmann I see no significant difference for bigstrand smallnbetween the two approaches. I believe this is more to do with overall pipeline than branch prediction per-se, there's also data alignment issues to consider. You should ask a new question for the particulars of why this is more processor/memory friendly, I'm sure it would gain a lot of interest, and receive a better answer than I can give here.
– Daniel
Jan 21 '16 at 8:48
@FlorianKaufmann: On x86,rep movsbis one of the most efficient ways to copy, at least for medium to large copies. Its micro-coded implementation has some near-constant startup overhead (on both AMD and Intel), e.g. on Sandybridge, ~15 to 40 cycles, plus 4 cycles per 64B cache line (best case). For small copies, an SSE loop is best because it doesn't have the startup overhead. But then it's subject to branch mispredicts.
– Peter Cordes
May 1 '16 at 2:46
add a comment |
You should write your own stream manipulator
- http://www.two-sdg.demon.co.uk/curbralan/papers/WritingStreamManipulators.html
cout << multi(5) << "whatever" <<
"lolcat";
14
writing a stream manipulator is a very complicated way of doing something very simple!
– Zero
Dec 22 '14 at 3:39
6
C++ is a very complicated way of doing something very simple.
– JDPeckham
Sep 2 '17 at 20:20
add a comment |
ITNOA
You can use 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();
add a comment |
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;
add a comment |
Your Answer
StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");
StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "1"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);
else
createEditor();
);
function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);
);
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f166630%2fhow-to-repeat-a-string-a-variable-number-of-times-in-c%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
8 Answers
8
active
oldest
votes
8 Answers
8
active
oldest
votes
active
oldest
votes
active
oldest
votes
In the particular case of repeating a single character, you can use std::string(size_type count, CharT ch):
std::string(5, '.') + "lolcat"
NB. This can't be used to repeat multi-character strings.
61
The OP asked for repeating a string, not a character.
– Florian Kaufmann
Jan 20 '16 at 21:10
add a comment |
In the particular case of repeating a single character, you can use std::string(size_type count, CharT ch):
std::string(5, '.') + "lolcat"
NB. This can't be used to repeat multi-character strings.
61
The OP asked for repeating a string, not a character.
– Florian Kaufmann
Jan 20 '16 at 21:10
add a comment |
In the particular case of repeating a single character, you can use std::string(size_type count, CharT ch):
std::string(5, '.') + "lolcat"
NB. This can't be used to repeat multi-character strings.
In the particular case of repeating a single character, you can use std::string(size_type count, CharT ch):
std::string(5, '.') + "lolcat"
NB. This can't be used to repeat multi-character strings.
edited Mar 25 at 17:06
Colonel Panic
84.5k63 gold badges312 silver badges399 bronze badges
84.5k63 gold badges312 silver badges399 bronze badges
answered Oct 3 '08 at 12:48
lukeluke
28.3k7 gold badges52 silver badges77 bronze badges
28.3k7 gold badges52 silver badges77 bronze badges
61
The OP asked for repeating a string, not a character.
– Florian Kaufmann
Jan 20 '16 at 21:10
add a comment |
61
The OP asked for repeating a string, not a character.
– Florian Kaufmann
Jan 20 '16 at 21:10
61
61
The OP asked for repeating a string, not a character.
– Florian Kaufmann
Jan 20 '16 at 21:10
The OP asked for repeating a string, not a character.
– Florian Kaufmann
Jan 20 '16 at 21:10
add a comment |
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.
add a comment |
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.
add a comment |
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.
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.
answered Oct 3 '08 at 16:43
Commodore JaegerCommodore Jaeger
23.9k4 gold badges49 silver badges44 bronze badges
23.9k4 gold badges49 silver badges44 bronze badges
add a comment |
add a comment |
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).
10
The OP asked for repeating a string, not a character.
– Brent
Dec 29 '17 at 19:45
@Brent The OP asked for both - "'n' spaces (or any string)", and then goes on to demonstrate their intent with a single period as the string. English is not many people's first language so you sometimes need to guess their exact requirements and when analysed, the question is really asking how to do this with a single character. I'm sorry you found my answer unhelpful enough you needed to down vote it.
– camh
Dec 30 '17 at 7:10
add a comment |
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).
10
The OP asked for repeating a string, not a character.
– Brent
Dec 29 '17 at 19:45
@Brent The OP asked for both - "'n' spaces (or any string)", and then goes on to demonstrate their intent with a single period as the string. English is not many people's first language so you sometimes need to guess their exact requirements and when analysed, the question is really asking how to do this with a single character. I'm sorry you found my answer unhelpful enough you needed to down vote it.
– camh
Dec 30 '17 at 7:10
add a comment |
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).
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).
answered Oct 3 '08 at 13:42
camhcamh
29.5k10 gold badges52 silver badges62 bronze badges
29.5k10 gold badges52 silver badges62 bronze badges
10
The OP asked for repeating a string, not a character.
– Brent
Dec 29 '17 at 19:45
@Brent The OP asked for both - "'n' spaces (or any string)", and then goes on to demonstrate their intent with a single period as the string. English is not many people's first language so you sometimes need to guess their exact requirements and when analysed, the question is really asking how to do this with a single character. I'm sorry you found my answer unhelpful enough you needed to down vote it.
– camh
Dec 30 '17 at 7:10
add a comment |
10
The OP asked for repeating a string, not a character.
– Brent
Dec 29 '17 at 19:45
@Brent The OP asked for both - "'n' spaces (or any string)", and then goes on to demonstrate their intent with a single period as the string. English is not many people's first language so you sometimes need to guess their exact requirements and when analysed, the question is really asking how to do this with a single character. I'm sorry you found my answer unhelpful enough you needed to down vote it.
– camh
Dec 30 '17 at 7:10
10
10
The OP asked for repeating a string, not a character.
– Brent
Dec 29 '17 at 19:45
The OP asked for repeating a string, not a character.
– Brent
Dec 29 '17 at 19:45
@Brent The OP asked for both - "'n' spaces (or any string)", and then goes on to demonstrate their intent with a single period as the string. English is not many people's first language so you sometimes need to guess their exact requirements and when analysed, the question is really asking how to do this with a single character. I'm sorry you found my answer unhelpful enough you needed to down vote it.
– camh
Dec 30 '17 at 7:10
@Brent The OP asked for both - "'n' spaces (or any string)", and then goes on to demonstrate their intent with a single period as the string. English is not many people's first language so you sometimes need to guess their exact requirements and when analysed, the question is really asking how to do this with a single character. I'm sorry you found my answer unhelpful enough you needed to down vote it.
– camh
Dec 30 '17 at 7:10
add a comment |
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
1
This won't work if all you want is the dots.
– uckelman
Oct 28 '11 at 15:40
5
only dots: change last line to...cout << "" << endl;
– musefan
Jan 11 '12 at 11:11
add a comment |
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
1
This won't work if all you want is the dots.
– uckelman
Oct 28 '11 at 15:40
5
only dots: change last line to...cout << "" << endl;
– musefan
Jan 11 '12 at 11:11
add a comment |
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
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
answered Jul 7 '10 at 9:50
IanIan
1011 silver badge2 bronze badges
1011 silver badge2 bronze badges
1
This won't work if all you want is the dots.
– uckelman
Oct 28 '11 at 15:40
5
only dots: change last line to...cout << "" << endl;
– musefan
Jan 11 '12 at 11:11
add a comment |
1
This won't work if all you want is the dots.
– uckelman
Oct 28 '11 at 15:40
5
only dots: change last line to...cout << "" << endl;
– musefan
Jan 11 '12 at 11:11
1
1
This won't work if all you want is the dots.
– uckelman
Oct 28 '11 at 15:40
This won't work if all you want is the dots.
– uckelman
Oct 28 '11 at 15:40
5
5
only dots: change last line to...
cout << "" << endl;– musefan
Jan 11 '12 at 11:11
only dots: change last line to...
cout << "" << endl;– musefan
Jan 11 '12 at 11:11
add a comment |
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)
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.
Your implementation does not 'minimize copying'. Mind that the+=within your for loop internally also has a loop of some sort which doesstr.size()iterations.str.size()grows in each outer loop iteration, so after each outer iteration the inner loop has to do more iterations. Your and the naive 'copy n times' implementation in total both copyn * periodcharacters. Your implementation does only one memory allocation because of the initialreserve. I guess you profiled your implementation with a rather smallstrand a bign, but not also with bigstrand a smalln.
– Florian Kaufmann
Jan 20 '16 at 21:02
@FlorianKaufmann Not sure why you've chosen to attack my answer. But by "minimise copying" I mean 'copying operations'. The idea being that copying a small number of big blocks is more efficient (for a variety of reasons) than copying a large number of small blocks. I potentially avoid an additional allocation on the input string over the naive method.
– Daniel
Jan 20 '16 at 23:57
1
It was a comment stating that I don't believe your claim that your solution is much better in terms of efficiency than the naive solution. In my measurements, compared to the naive solution, your code is faster with small strings and many repetitions, but slower with long strings and few repetitions. Could you provide links explaining in more detail the variety of reasons why copying a few big blocks has a higher performance than copying many small blocks? I can think of branch prediction. Regarding CPU cache I am unsure which variant is preferred.
– Florian Kaufmann
Jan 21 '16 at 7:42
@FlorianKaufmann I see no significant difference for bigstrand smallnbetween the two approaches. I believe this is more to do with overall pipeline than branch prediction per-se, there's also data alignment issues to consider. You should ask a new question for the particulars of why this is more processor/memory friendly, I'm sure it would gain a lot of interest, and receive a better answer than I can give here.
– Daniel
Jan 21 '16 at 8:48
@FlorianKaufmann: On x86,rep movsbis one of the most efficient ways to copy, at least for medium to large copies. Its micro-coded implementation has some near-constant startup overhead (on both AMD and Intel), e.g. on Sandybridge, ~15 to 40 cycles, plus 4 cycles per 64B cache line (best case). For small copies, an SSE loop is best because it doesn't have the startup overhead. But then it's subject to branch mispredicts.
– Peter Cordes
May 1 '16 at 2:46
add a comment |
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)
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.
Your implementation does not 'minimize copying'. Mind that the+=within your for loop internally also has a loop of some sort which doesstr.size()iterations.str.size()grows in each outer loop iteration, so after each outer iteration the inner loop has to do more iterations. Your and the naive 'copy n times' implementation in total both copyn * periodcharacters. Your implementation does only one memory allocation because of the initialreserve. I guess you profiled your implementation with a rather smallstrand a bign, but not also with bigstrand a smalln.
– Florian Kaufmann
Jan 20 '16 at 21:02
@FlorianKaufmann Not sure why you've chosen to attack my answer. But by "minimise copying" I mean 'copying operations'. The idea being that copying a small number of big blocks is more efficient (for a variety of reasons) than copying a large number of small blocks. I potentially avoid an additional allocation on the input string over the naive method.
– Daniel
Jan 20 '16 at 23:57
1
It was a comment stating that I don't believe your claim that your solution is much better in terms of efficiency than the naive solution. In my measurements, compared to the naive solution, your code is faster with small strings and many repetitions, but slower with long strings and few repetitions. Could you provide links explaining in more detail the variety of reasons why copying a few big blocks has a higher performance than copying many small blocks? I can think of branch prediction. Regarding CPU cache I am unsure which variant is preferred.
– Florian Kaufmann
Jan 21 '16 at 7:42
@FlorianKaufmann I see no significant difference for bigstrand smallnbetween the two approaches. I believe this is more to do with overall pipeline than branch prediction per-se, there's also data alignment issues to consider. You should ask a new question for the particulars of why this is more processor/memory friendly, I'm sure it would gain a lot of interest, and receive a better answer than I can give here.
– Daniel
Jan 21 '16 at 8:48
@FlorianKaufmann: On x86,rep movsbis one of the most efficient ways to copy, at least for medium to large copies. Its micro-coded implementation has some near-constant startup overhead (on both AMD and Intel), e.g. on Sandybridge, ~15 to 40 cycles, plus 4 cycles per 64B cache line (best case). For small copies, an SSE loop is best because it doesn't have the startup overhead. But then it's subject to branch mispredicts.
– Peter Cordes
May 1 '16 at 2:46
add a comment |
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)
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.
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)
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.
edited Sep 5 '17 at 13:29
answered Dec 16 '15 at 20:39
DanielDaniel
3,3833 gold badges18 silver badges41 bronze badges
3,3833 gold badges18 silver badges41 bronze badges
Your implementation does not 'minimize copying'. Mind that the+=within your for loop internally also has a loop of some sort which doesstr.size()iterations.str.size()grows in each outer loop iteration, so after each outer iteration the inner loop has to do more iterations. Your and the naive 'copy n times' implementation in total both copyn * periodcharacters. Your implementation does only one memory allocation because of the initialreserve. I guess you profiled your implementation with a rather smallstrand a bign, but not also with bigstrand a smalln.
– Florian Kaufmann
Jan 20 '16 at 21:02
@FlorianKaufmann Not sure why you've chosen to attack my answer. But by "minimise copying" I mean 'copying operations'. The idea being that copying a small number of big blocks is more efficient (for a variety of reasons) than copying a large number of small blocks. I potentially avoid an additional allocation on the input string over the naive method.
– Daniel
Jan 20 '16 at 23:57
1
It was a comment stating that I don't believe your claim that your solution is much better in terms of efficiency than the naive solution. In my measurements, compared to the naive solution, your code is faster with small strings and many repetitions, but slower with long strings and few repetitions. Could you provide links explaining in more detail the variety of reasons why copying a few big blocks has a higher performance than copying many small blocks? I can think of branch prediction. Regarding CPU cache I am unsure which variant is preferred.
– Florian Kaufmann
Jan 21 '16 at 7:42
@FlorianKaufmann I see no significant difference for bigstrand smallnbetween the two approaches. I believe this is more to do with overall pipeline than branch prediction per-se, there's also data alignment issues to consider. You should ask a new question for the particulars of why this is more processor/memory friendly, I'm sure it would gain a lot of interest, and receive a better answer than I can give here.
– Daniel
Jan 21 '16 at 8:48
@FlorianKaufmann: On x86,rep movsbis one of the most efficient ways to copy, at least for medium to large copies. Its micro-coded implementation has some near-constant startup overhead (on both AMD and Intel), e.g. on Sandybridge, ~15 to 40 cycles, plus 4 cycles per 64B cache line (best case). For small copies, an SSE loop is best because it doesn't have the startup overhead. But then it's subject to branch mispredicts.
– Peter Cordes
May 1 '16 at 2:46
add a comment |
Your implementation does not 'minimize copying'. Mind that the+=within your for loop internally also has a loop of some sort which doesstr.size()iterations.str.size()grows in each outer loop iteration, so after each outer iteration the inner loop has to do more iterations. Your and the naive 'copy n times' implementation in total both copyn * periodcharacters. Your implementation does only one memory allocation because of the initialreserve. I guess you profiled your implementation with a rather smallstrand a bign, but not also with bigstrand a smalln.
– Florian Kaufmann
Jan 20 '16 at 21:02
@FlorianKaufmann Not sure why you've chosen to attack my answer. But by "minimise copying" I mean 'copying operations'. The idea being that copying a small number of big blocks is more efficient (for a variety of reasons) than copying a large number of small blocks. I potentially avoid an additional allocation on the input string over the naive method.
– Daniel
Jan 20 '16 at 23:57
1
It was a comment stating that I don't believe your claim that your solution is much better in terms of efficiency than the naive solution. In my measurements, compared to the naive solution, your code is faster with small strings and many repetitions, but slower with long strings and few repetitions. Could you provide links explaining in more detail the variety of reasons why copying a few big blocks has a higher performance than copying many small blocks? I can think of branch prediction. Regarding CPU cache I am unsure which variant is preferred.
– Florian Kaufmann
Jan 21 '16 at 7:42
@FlorianKaufmann I see no significant difference for bigstrand smallnbetween the two approaches. I believe this is more to do with overall pipeline than branch prediction per-se, there's also data alignment issues to consider. You should ask a new question for the particulars of why this is more processor/memory friendly, I'm sure it would gain a lot of interest, and receive a better answer than I can give here.
– Daniel
Jan 21 '16 at 8:48
@FlorianKaufmann: On x86,rep movsbis one of the most efficient ways to copy, at least for medium to large copies. Its micro-coded implementation has some near-constant startup overhead (on both AMD and Intel), e.g. on Sandybridge, ~15 to 40 cycles, plus 4 cycles per 64B cache line (best case). For small copies, an SSE loop is best because it doesn't have the startup overhead. But then it's subject to branch mispredicts.
– Peter Cordes
May 1 '16 at 2:46
Your implementation does not 'minimize copying'. Mind that the
+= within your for loop internally also has a loop of some sort which does str.size() iterations. str.size() grows in each outer loop iteration, so after each outer iteration the inner loop has to do more iterations. Your and the naive 'copy n times' implementation in total both copy n * period characters. Your implementation does only one memory allocation because of the initial reserve. I guess you profiled your implementation with a rather small str and a big n, but not also with big str and a small n.– Florian Kaufmann
Jan 20 '16 at 21:02
Your implementation does not 'minimize copying'. Mind that the
+= within your for loop internally also has a loop of some sort which does str.size() iterations. str.size() grows in each outer loop iteration, so after each outer iteration the inner loop has to do more iterations. Your and the naive 'copy n times' implementation in total both copy n * period characters. Your implementation does only one memory allocation because of the initial reserve. I guess you profiled your implementation with a rather small str and a big n, but not also with big str and a small n.– Florian Kaufmann
Jan 20 '16 at 21:02
@FlorianKaufmann Not sure why you've chosen to attack my answer. But by "minimise copying" I mean 'copying operations'. The idea being that copying a small number of big blocks is more efficient (for a variety of reasons) than copying a large number of small blocks. I potentially avoid an additional allocation on the input string over the naive method.
– Daniel
Jan 20 '16 at 23:57
@FlorianKaufmann Not sure why you've chosen to attack my answer. But by "minimise copying" I mean 'copying operations'. The idea being that copying a small number of big blocks is more efficient (for a variety of reasons) than copying a large number of small blocks. I potentially avoid an additional allocation on the input string over the naive method.
– Daniel
Jan 20 '16 at 23:57
1
1
It was a comment stating that I don't believe your claim that your solution is much better in terms of efficiency than the naive solution. In my measurements, compared to the naive solution, your code is faster with small strings and many repetitions, but slower with long strings and few repetitions. Could you provide links explaining in more detail the variety of reasons why copying a few big blocks has a higher performance than copying many small blocks? I can think of branch prediction. Regarding CPU cache I am unsure which variant is preferred.
– Florian Kaufmann
Jan 21 '16 at 7:42
It was a comment stating that I don't believe your claim that your solution is much better in terms of efficiency than the naive solution. In my measurements, compared to the naive solution, your code is faster with small strings and many repetitions, but slower with long strings and few repetitions. Could you provide links explaining in more detail the variety of reasons why copying a few big blocks has a higher performance than copying many small blocks? I can think of branch prediction. Regarding CPU cache I am unsure which variant is preferred.
– Florian Kaufmann
Jan 21 '16 at 7:42
@FlorianKaufmann I see no significant difference for big
str and small n between the two approaches. I believe this is more to do with overall pipeline than branch prediction per-se, there's also data alignment issues to consider. You should ask a new question for the particulars of why this is more processor/memory friendly, I'm sure it would gain a lot of interest, and receive a better answer than I can give here.– Daniel
Jan 21 '16 at 8:48
@FlorianKaufmann I see no significant difference for big
str and small n between the two approaches. I believe this is more to do with overall pipeline than branch prediction per-se, there's also data alignment issues to consider. You should ask a new question for the particulars of why this is more processor/memory friendly, I'm sure it would gain a lot of interest, and receive a better answer than I can give here.– Daniel
Jan 21 '16 at 8:48
@FlorianKaufmann: On x86,
rep movsb is one of the most efficient ways to copy, at least for medium to large copies. Its micro-coded implementation has some near-constant startup overhead (on both AMD and Intel), e.g. on Sandybridge, ~15 to 40 cycles, plus 4 cycles per 64B cache line (best case). For small copies, an SSE loop is best because it doesn't have the startup overhead. But then it's subject to branch mispredicts.– Peter Cordes
May 1 '16 at 2:46
@FlorianKaufmann: On x86,
rep movsb is one of the most efficient ways to copy, at least for medium to large copies. Its micro-coded implementation has some near-constant startup overhead (on both AMD and Intel), e.g. on Sandybridge, ~15 to 40 cycles, plus 4 cycles per 64B cache line (best case). For small copies, an SSE loop is best because it doesn't have the startup overhead. But then it's subject to branch mispredicts.– Peter Cordes
May 1 '16 at 2:46
add a comment |
You should write your own stream manipulator
- http://www.two-sdg.demon.co.uk/curbralan/papers/WritingStreamManipulators.html
cout << multi(5) << "whatever" <<
"lolcat";
14
writing a stream manipulator is a very complicated way of doing something very simple!
– Zero
Dec 22 '14 at 3:39
6
C++ is a very complicated way of doing something very simple.
– JDPeckham
Sep 2 '17 at 20:20
add a comment |
You should write your own stream manipulator
- http://www.two-sdg.demon.co.uk/curbralan/papers/WritingStreamManipulators.html
cout << multi(5) << "whatever" <<
"lolcat";
14
writing a stream manipulator is a very complicated way of doing something very simple!
– Zero
Dec 22 '14 at 3:39
6
C++ is a very complicated way of doing something very simple.
– JDPeckham
Sep 2 '17 at 20:20
add a comment |
You should write your own stream manipulator
- http://www.two-sdg.demon.co.uk/curbralan/papers/WritingStreamManipulators.html
cout << multi(5) << "whatever" <<
"lolcat";
You should write your own stream manipulator
- http://www.two-sdg.demon.co.uk/curbralan/papers/WritingStreamManipulators.html
cout << multi(5) << "whatever" <<
"lolcat";
answered Oct 3 '08 at 12:53
RoskotoRoskoto
8841 gold badge11 silver badges26 bronze badges
8841 gold badge11 silver badges26 bronze badges
14
writing a stream manipulator is a very complicated way of doing something very simple!
– Zero
Dec 22 '14 at 3:39
6
C++ is a very complicated way of doing something very simple.
– JDPeckham
Sep 2 '17 at 20:20
add a comment |
14
writing a stream manipulator is a very complicated way of doing something very simple!
– Zero
Dec 22 '14 at 3:39
6
C++ is a very complicated way of doing something very simple.
– JDPeckham
Sep 2 '17 at 20:20
14
14
writing a stream manipulator is a very complicated way of doing something very simple!
– Zero
Dec 22 '14 at 3:39
writing a stream manipulator is a very complicated way of doing something very simple!
– Zero
Dec 22 '14 at 3:39
6
6
C++ is a very complicated way of doing something very simple.
– JDPeckham
Sep 2 '17 at 20:20
C++ is a very complicated way of doing something very simple.
– JDPeckham
Sep 2 '17 at 20:20
add a comment |
ITNOA
You can use 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();
add a comment |
ITNOA
You can use 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();
add a comment |
ITNOA
You can use 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();
ITNOA
You can use 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();
answered Apr 2 '18 at 14:51
sorosh_sabzsorosh_sabz
4067 silver badges23 bronze badges
4067 silver badges23 bronze badges
add a comment |
add a comment |
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;
add a comment |
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;
add a comment |
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;
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;
answered Apr 10 '18 at 1:12
PavelPavel
9,2799 gold badges51 silver badges90 bronze badges
9,2799 gold badges51 silver badges90 bronze badges
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f166630%2fhow-to-repeat-a-string-a-variable-number-of-times-in-c%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Someone provide an answer using QString?
– Akiva
Dec 12 '15 at 17:46