C++自定义流操纵器,用于更改流上的下一个字符串
C++ custom stream manipulator that changes next string on stream
我想在这里做与接受的答案相同的事情,但我想使用 std::string,而不是使用 int: C++自定义流操纵器,用于更改流中的下一个项目
链接的答案显示了实现流格式化行为自定义的"正确"方法,但它要求格式化的输出操作是可扩展的 - 这可能是正确的,原因如下:
- 因为您已经为自己的类型编写了
operator<<
并且可以完全控制行为,或者 - 因为您正在打印标准库通过
locale
明确允许您控制的类型(例如,打印带有不同数字分隔符的整数(。
这些都不是std::string
的情况。目的是std::string
完全包含要打印的字符。这并非不可能,但我下面展示的解决方案是地狱般的笨拙,我真的不推荐它!string
应已包含格式化的内容,不应由打印操作来更改该内容。
诀窍是我们想调用我们自己的operator<<
,我们无法控制string
的类型,所以我们控制流的类型。
#include <algorithm>
#include <iostream>
#include <string>
// Not really a stream, but works enough like one for our purposes
struct UpperStream {
std::ostream& d_originalStream;
UpperStream(std::ostream& originalStream)
: d_originalStream(originalStream)
{}
};
// Trick to turn a normal stream into our magic type
struct UpperHelper {} makeNextStringUpper;
UpperStream operator<<(std::ostream& os, UpperHelper)
{ return os; }
// Special printing for strings
std::ostream& operator<<(UpperStream const& us, std::string s)
{
auto l = us.d_originalStream.getloc();
std::transform(std::cbegin(s),
std::cend(s),
std::begin(s),
[=](char c){return std::toupper(c, l);});
return us.d_originalStream << s;
}
// Default to normal printing for everything else, and then go back to normal
// stream behaviour
template <typename T>
std::ostream& operator<<(UpperStream const& us, T&& t)
{ return us.d_originalStream << t; }
int main()
{
using namespace std::string_literals;
std::cout << makeNextStringUpper << "Hello, World!n"s;
std::cout << makeNextStringUpper << 123 << " Hello, World!n"s;
}
这将打印:
HELLO, WORLD!
123 Hello, World!
老实说,试图让它看起来像一个流操纵器的整个业务非常奇怪。在string
本身上工作有什么问题?
std::string toUpper(std::string s)
{
std::locale l;
std::transform(std::cbegin(s), std::cend(s), std::begin(s),
[=](char c){return std::toupper(c, l);});
return s;
}
int main()
{
std::cout << toUpper("Hello, World!n"s);
}
相关文章:
- 为什么 sscanf 无法从一个字符串中读取uint64_t和字符?
- 如何检查一个c++字符串中有多少相同的字符/数字
- 如何在不知道对应关系的情况下在字符串中搜索字符并将其分配给另一个字符?
- C++自定义流操纵器,用于更改流上的下一个字符串
- 如何在没有运算符>>的情况下从字符串流返回下一个令牌?
- 快速从文件中读取下一个字符串,而无需移动文件的位置
- 如何使用字符串字符数组中的 ++ 运算符访问下一个字符串
- 使用getline()将字符串输入到程序中会导致下一个输入出现某种溢出
- 试图在字符串中找到一个数字,更改它,放回并找到下一个数字
- 为什么一个指向char的C++指针在缺少null终止符的情况下充当字符串
- strtok() - 为什么必须传递 NULL 指针才能获取字符串中的下一个标记
- 按字典顺序从范围中获取下一个数字(不包含所有字符串的容器)
- 如何在字符串中的任意位置提取下一个整数
- 如何使用 std::regex 查找字符串中的下一个匹配项
- 虽然循环不输出子字符串的下一个实例
- std::out_of_range basic_string 当从 vector 中的空字符串转到下一个元素时
- 如何在不使用 variable_name.at() 的情况下引用字符串的最后一个字符
- 如何在C++中的字符串数组中找到下一个空闲元素,然后将数据附加到它
- 检查>>提取的下一个值是字符串还是整数
- 多次调用返回字符串的Lua函数.如何使它有跨到下一个实例的字段