可以说我有string foo("lorem ipsum")
。现在我想从 打印最大数量的字符foo
,假设x
它保证小于foo.size()
。
这是非常大陆printf
:
printf("%.*s", x, foo.data());
但我能在流中找到这样做的唯一方法是构建一个临时的string
:
cout << string(foo, x);
是否有一个操纵器可以让我设置流的精度,或者正在构建一个临时string
的所有可供我使用的东西?
这不是流操纵器,但您可以使用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),这是一些轻量级的子字符串包装器,它是 ostream-able 的。string_view
只要您提到 ( ) 的保证成立,以下行将打印 的第一个x
字符而不将其复制到临时字符串:foo
x >= foo.size()
cout << string_view(foo.data(), x);
如果保证不再成立,setw
请在字符串较短时使用空格填充字段,以便打印固定字段长度的x
字符。构造string_view
函数需要一个适当的限制长度,因为它不知道“真实”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
or时可用17
。