In python, the following instruction: print 'a'*5
would output aaaaa
. How would one write something similar in C++ in conjunction with std::ostream
s in order to avoid a for
construct?
The obvious way would be with fill_n
:
std::fill_n(std::ostream_iterator<char>(std::cout), 5, 'a');
Another possibility would be be to just construct a string:
std::cout << std::string(5, 'a');
ostreambuf_iterator
? –
Mar std:fill_n
operation for a stream, but, more importantly, it avoids the dynamic memory allocation required to construct (and then destroy) a string. (Why they cannot elide the dynamic memory allocation for a compile-time constant string... I'm sure there's a good reason...) –
Clean In C++20 you can easily write multiple copies of a character with std::format
:
std::cout << std::format("{:a<5}", "");
Output:
aaaaa
If std::format
is not available you can use the {fmt} library, it is based on. {fmt} also provides the print
function that makes this even easier and more efficient (godbolt):
fmt::print("{:a<5}", "");
Apart from being less verbose than using ostream[_iterator]
this also guarantees that the output doesn't interleave with the output of other threads, if any.
Disclaimer: I'm the author of {fmt} and C++20 std::format
.
Use some tricky way:
os << setw(n) << setfill(c) << "";
Where n is number of char c to write
setfill(' ')
after works here. BTW solution with fill_n can be broken by os << setw(5) << left << fill_n(...)
- producing a aaaa
:D... –
Inmate std::fill_n
in that way. std::fill_n
returns an iterator, and there's no overload of operator<<
to write an iterator to a stream. You could make it compile by adding that yourself, but it doesn't seem to be something that's at all likely to happen by accident (and if you did it, your output would mostly be whatever you wrote into that overload of operator<<
, not any pre-existing behavior). –
Campanulaceous You can do something like that by overloading the *
operator for std::string. Here is a small example
#include<iostream>
#include<string>
std::string operator*(const std::string &c,int n)
{
std::string str;
for(int i=0;i<n;i++)
str+=c;
return str;
}
int main()
{
std::string str= "foo";
std::cout<< str*5 <<"\n";
}
The standard does not provide any elegant way. But one possibility (my favourite) is to use a proxy object like this
class repeat_char
{
public:
repeat_char(char c, size_t count) : c(c), count(count) {}
friend std::ostream & operator<<(std::ostream & os, repeat_char repeat)
{
while (repeat.count-- > 0)
os << repeat.c;
return os;
}
private:
char c;
size_t count;
};
and then use it this way
std::cout << repeat_char(' ', 5);
template <class T> struct print_n { print_n(T v, size_t c) .... };
-- os << print_n("Ha", 3);
–
Inmate © 2022 - 2024 — McMap. All rights reserved.
"abc"_s * 3
orstd::string ("abc") * 3
to mean"abcabcabc"
on this question. – Testeroperator*(string, size_t)
forstring
is exactly as bad (or good) as overloadingoperator+(string, string)
. No better nor worse - the meaning of multiplication by a natural number as repeated addition is fundamental mathematics, there's no excuse for misunderstanding one but not the other. It's probably also partly because your question complains about the standard and proposes a change to it (neither of which is on topic) in addition to asking a question about the motivation :-p – Persephone