字符串的流精度修饰符

Stream Precision Modifier for strings

假设我有 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

Live Example

没有"stream manipulator"在指定宽度后切断字符串。

你要找的基本上是 string_view(1),这是一些轻量级的子字符串包装器,它是 ostream-able.

以下行将打印 foo 的前 x 个字符而不将其复制到临时字符串,只要您提到的保证 (x >= foo.size()) 成立:

cout << string_view(foo.data(), x);

如果保证不再成立,当字符串较短时,使用 setw 用空格填充字段,以便打印 x 个字符的固定字段长度。 string_view 构造函数需要适当的 bound-limited 长度,因为它不知道 "real" 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) 这个 class 目前是实验性的,还没有在标准中。据我所知,它可能会出现在 C++17 中,并且在使用 -std=c++1y17.[=52 时从 g++ 4.9 开始在 <experimental/string_view> 中作为 std::experimental::string_view 可用=]