如何使用输入和输出流操纵器将所有空白字符替换为另一个字符?

时间:2019-06-18 15:20:11

标签: c++ c++11 c++14 manipulators

例如,我使用std::cin从用户那里得到输入:

"This is a sample program"

我想用另一个字符替换每个空格,并像下面那样显示它:

"This\is\a\sample\program"

注意:其他字符可以是任何字符。例如:*&$,等等。

我想使用流操纵器来做到这一点。有可能吗?

这是一些我使用std :: getline尝试过的示例代码,但这不是我期望的那种代码。我想使用任何现有的i/o stream Manipulators或我自己的操纵器来完成此操作。

#include <iostream>
#include <sstream>
#include <string>

using namespace std;
string spaceToStar(string text){
    for (int i=0;i<sizeof(text);i++){
        if(text[i] == ' ')
            text[i] = '*';
    }
    return text;
}

int main () {
    string text, s;
    cout << "enter your line: " << endl;
    getline(cin, text);

    s = spaceToStar(text);

    cout << s << endl;


  return 0;
}

1 个答案:

答案 0 :(得分:2)

您可以替换通过流缓冲区输入的字符,并创建用于简化语法的操纵器。这是一种实现方法,可能不是最佳实现,但它可以工作。

#include <iostream>
#include <memory>
using namespace std;

namespace xalloc {
  int from(){static int x=std::ios_base::xalloc();return x;}
  int to(){static int x=std::ios_base::xalloc();return x;}
}

template<class cT>
struct filterbuf : std::basic_streambuf<cT> {
  std::basic_streambuf<cT>* sbuf;
  std::ios_base& ios;
public:
  filterbuf(std::basic_ostream<cT>& str) : sbuf(str.rdbuf()), ios(str) {}
  int overflow(typename filterbuf::int_type c) {
      if (filterbuf::traits_type::eq_int_type(c, ios.iword(xalloc::from()))) {
          return this->sbuf->sputc(ios.iword(xalloc::to()));
      }
      return this->sbuf->sputc(c);
  }
  int sync() { return this->sbuf->pubsync(); }
};


template<class cT>
struct reinterpret { 
  cT from, to;
  template<class T>reinterpret(T f, T t) : from(f), to(t) {}
};

std::basic_ostream<cT>& operator<<(std::basic_ostream<cT>& os, reinterpret rt) {
  static auto nofree=[](std::streambuf*){};
  static std::unique_ptr<filterbuf<cT>, decltype(nofree)> buffer(
    new filterbuf<cT>(os),nofree
  );
  os.iword(xalloc::from()) = rt.from;
  os.iword(xalloc::to()) = rt.to;
  if (os.rdbuf() != buffer.get()) os.rdbuf(buffer.get());
  return os;
}

template<class T>
reinterpret(T, T) -> reinterpret<T>;


int main() {
  cout << reinterpret(' ', '\\') << "A B C D\n"; // A\B\C\D
  cout << reinterpret(' ', '*') << "A B C D\n"; // A*B*C*D
}