Lets say I have string foo("lorem ipsum")
. Now i want to print a maximum number of characters from foo
, let's say x
which is guaranteed to be smaller than foo.size()
.
This is very continent in printf
:
printf("%.*s", x, foo.data());
But the only way I can find to do this in a stream is to construct a temporary string
:
cout << string(foo, x);
Is there a manipulator that will let me set the precision for streams, or is constructing a temporary string
all that's available to me?
There is no "stream manipulator" to cut off strings after a specified width.
What you're looking for is basically string_view
(1), that is some light weight substring wrapper which is ostream-able.
The following line would print the first x
characters of foo
without copying it to a temporary string, as long as the guarantee you mention (x >= foo.size()
) holds:
cout << string_view(foo.data(), x);
In case the guarantee doesn't hold anymore, use setw
to fill the field with whitespaces when the string is shorter, in order to print a fixed field length of x
characters. The string_view
constructor needs a properly bound-limited length since it doesn't know the size of the "real" std::string
object, thus we use min
to limit x
to the length of the string:
cout << setw(x) << string_view(foo.data(), min(x, foo.size()));
If you don't want to or can't use string_view
, you can write your own light weight wrapper just for the purpose of printing a substring with ostream.
class substr {
const std::string & s;
std::size_t len;
friend std::ostream& operator<<(std::ostream& os, const substr &ss) {
std::copy(ss.s.begin(), ss.s.begin() + std::min(ss.len, ss.s.size()),
std::ostream_iterator<char>(os));
return os;
}
public:
substr(const std::string & s, std::size_t len) : s(s), len(len) {}
};
The usage is then:
cout << substr(foo, x);
(1) This class is currently experimental and not yet in the standard. As far as I know, it probably will be in C++17 and is available as std::experimental::string_view
in <experimental/string_view>
since g++ 4.9 when using -std=c++1y
or 17
.