【问题标题】:Is it possible to manipulate some text with an user-defined I/O manipulator?是否可以使用用户定义的 I/O 操纵器来操纵某些文本?
【发布时间】:2012-04-09 16:39:13
【问题描述】:

在将 std::cin 中的一些文本插入std::string 之前,是否有一种(干净的)方法来操作它,以便以下操作:

cin >> setw(80) >> Uppercase >> mystring;

其中 mystring 是 std::string(我不想对字符串使用任何包装器)。 Uppercase 是一个操纵者。我认为它需要直接作用于缓冲区中的字符(无论现在认为是大写而不是小写)。这样的操纵器似乎很难以干净的方式实现,因为据我所知,用户定义的操纵器用于轻松更改或混合一些预先确定的格式标志。

【问题讨论】:

标签: c++


【解决方案1】:

(非扩展)操纵器通常只设置提取器随后读取和响应的标志和数据。 (这就是 xallociwordpword 的用途。)显然,你可以做的就是写一些类似于 std::get_money 的东西:

struct uppercasify {
  uppercasify(std::string &s) : ref(s) {}
  uppercasify(const uppercasify &other) : ref(other.ref) {}
  std::string &ref;
}
std::istream &operator>>(std::istream &is, uppercasify uc) { // or &&uc in C++11
  is >> uc.ref;
  boost::to_upper(uc.ref);
  return is;
}

cin >> setw(80) >> uppercasify(mystring);

另外,cin >> uppercase 可能返回的不是对cin 的引用,而是一些(模板)包装类uppercase_istream 的实例化,以及operator>> 的相应重载。我不认为让操纵器修改底层流缓冲区的内容是个好主意。

如果你足够绝望,我想你也可以imbue 一个手工制作的语言环境,导致字符串大写。不过,我认为我不会让这样的事情通过代码审查——它只是在等待下一个编写代码的人给你惊喜。

【讨论】:

  • 感谢您的回答。也许你的意思是说 std::istream &operator>>(std::istream &is, const uppercasify &uc) 因为 uppercasify(mystring) 是一个临时对象
  • 它不能与const 一起使用,因为代码在uc.ref 上使用了非const 操作。删除 & 或使用 C++11 并使用 &&。但是 Anon 的 boost 指针可能是我无论如何都会遵循的。
  • 对不起,如果我坚持的话,但是 ref 是一个引用,而不是一个 const 引用,所以即使使用 const uppercasify& ,非 const 操作在 ref 上也应该没问题,不是吗?我的 gcc 编译器仅在我使用 const uppercasify& for operator >> (c++ 98 here) 时编译上述代码
  • 对不起,我忘了“继承” cv-qualifiers 不适用于引用类型。 (§3.9.3/3,如果有人想查一下。)你是对的。
【解决方案2】:

您可能想查看 boost iostreams。它的框架允许定义可以操纵流的过滤器。 http://www.boost.org/doc/libs/1_49_0/libs/iostreams/doc/index.html

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-12-31
    • 1970-01-01
    • 2010-11-11
    • 2019-09-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多