Как я могу заменить все символы пробела на другой символ, используя манипуляторы потока ввода и вывода? - PullRequest
0 голосов
/ 18 июня 2019

Например, я получаю ввод от пользователя, используя 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 Ответ

2 голосов
/ 18 июня 2019

Вы можете заменить символы, когда они проходят через буфер потока, и создать манипулятор для упрощенного синтаксиса.Вот один из способов сделать это, возможно, не самая лучшая реализация, но она работает.

#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
}
...