0

可以说我有string foo("lorem ipsum")。现在我想从 打印最大数量的字符foo,假设x它保证小于foo.size()

这是非常大陆printf

printf("%.*s", x, foo.data());

但我能在流中找到这样做的唯一方法是构建一个临时的string

cout << string(foo, x);

是否有一个操纵器可以让我设置流的精度,或者正在构建一个临时string的所有可供我使用的东西?

4

2 回答 2

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

Live Example

于 2016-01-12T17:24:55.900 回答
2

没有“流操纵器”可以在指定宽度后切断字符串。

您正在寻找的基本上是(1),这是一些轻量级的子字符串包装器,它是 ostream-able 的。string_view

只要您提到 ( ) 的保证成立,以下行将打印 的第一个x字符而不将其复制到临时字符串:foox >= 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);

Live Example


(1) 该类目前处于实验阶段,尚未纳入标准。据我所知,它可能会在 C++17 中使用,并且std::experimental::string_view<experimental/string_view>g++ 4.9 开始在使用-std=c++1yor时可用17

于 2016-01-12T23:46:46.027 回答