字符串的流精度修饰符
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
没有"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);
(1) 这个 class 目前是实验性的,还没有在标准中。据我所知,它可能会出现在 C++17 中,并且在使用 -std=c++1y
或 17
.[=52 时从 g++ 4.9 开始在 <experimental/string_view>
中作为 std::experimental::string_view
可用=]
假设我有 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
没有"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);
(1) 这个 class 目前是实验性的,还没有在标准中。据我所知,它可能会出现在 C++17 中,并且在使用 -std=c++1y
或 17
.[=52 时从 g++ 4.9 开始在 <experimental/string_view>
中作为 std::experimental::string_view
可用=]