用于字符串的流精度修改器

时间:2016-01-12 17:16:29

标签: c++ printf precision cout iomanip

假设我有string foo("lorem ipsum")。现在我要打印foo中的最大字符数,假设x保证小于foo.size()

这是非常大陆的printf

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

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

cout << string(foo, x);

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

2 个答案:

答案 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

Live Example

答案 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对象,因此我们使用minx限制为字符串的长度:

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++1y17时。