假设我有string foo("lorem ipsum")
。现在我要打印foo
中的最大字符数,假设x
保证小于foo.size()
。
这是非常大陆的printf
:
printf("%.*s", x, foo.data());
但我能在流中找到这样做的唯一方法是构建一个临时的string
:
cout << string(foo, x);
是否有一个操纵器可以让我设置流的精度,或者是否构建了一个临时的string
可供我使用的那个?
答案 0 :(得分:2)
这不是流操纵器,但您可以使用std::copy
并将所需的字符数复制到输出流中。这样可以避免构造临时字符串。
int main() {
std::string s = "this is a test";
std::copy(s.begin(), s.begin() + 7, std::ostream_iterator<char>(std::cout));
return 0;
}
输出:
this is
答案 1 :(得分:2)
没有&#34;流操纵器&#34;在指定宽度后切断字符串。
您正在寻找的内容基本上是string_view
(1),这是一个轻量级的子字符串包装器,它是ostream能够的。
以下行会打印x
的第一个foo
字符,而不会将其复制到临时字符串,只要您提到的保证(x >= foo.size()
)成立:
cout << string_view(foo.data(), x);
如果保证不再保留,请在字符串较短时使用setw
用空格填充字段,以便打印固定字段长度为x
个字符。 string_view
构造函数需要一个适当限制的长度,因为它不知道&#34; real&#34;的大小。 std::string
对象,因此我们使用min
将x
限制为字符串的长度:
cout << setw(x) << string_view(foo.data(), min(x, foo.size()));
如果您不想或不能使用string_view
,您可以编写自己的轻量级包装,只是为了使用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) {}
};
然后使用:
cout << substr(foo, x);
(1)该课程目前是实验性的,尚未达到标准。据我所知,它可能在C ++ 17中,并且在std::experimental::string_view
中以<experimental/string_view>
提供,因为g ++ 4.9在使用-std=c++1y
或17
时。