3

Is there a (clean) way to manipulate some text from std::cin before inserting it into a std::string, so that the following would work:

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

where mystring is std::string (I don't want to use any wrappers for strings). Uppercase is a manipulator. I think it needs to act on the Chars in the buffer directly (no matter what is considered uppercase rather than lowercase now). Such a manipulator seems difficult to implement in a clean way, as user-defined manipulators, as far as I know, are used to just change or mix some pre-determined format flags easily.

Martin
  • 9,089
  • 11
  • 52
  • 87
  • Related but not identical: http://stackoverflow.com/questions/1391746/how-to-easily-indent-output-to-ofstream – Robᵩ Apr 09 '12 at 16:51

2 Answers2

3

You may want to check out boost iostreams. Its framework allows defining filters which can manipulate the stream. http://www.boost.org/doc/libs/1_49_0/libs/iostreams/doc/index.html

Christopher Creutzig
  • 8,656
  • 35
  • 45
Anon Mail
  • 4,660
  • 1
  • 18
  • 21
3

(Non-extended) manipulators usually only set flags and data which the extractors afterwards read and react to. (That is what xalloc, iword, and pword are for.) What you could, obviously, do, is to write something analogous to 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);

Alternatively, cin >> uppercase could return not a reference to cin, but an instantiation of some (template) wrapper class uppercase_istream, with the corresponding overload for operator>>. I don't think having a manipulator modify the underlying stream buffer's contents is a good idea.

If you're desperate enough, I guess you could also imbue a hand-crafted locale resulting in uppercasing strings. I don't think I'd let anything like that go through a code review, though – it's simply just waiting to surprise and bite the next person working on the code.

Christopher Creutzig
  • 8,656
  • 35
  • 45
  • thanks for the answer. Maybe you meant to say std::istream &operator>>(std::istream &is, const uppercasify &uc) since uppercasify(mystring) is a temporary object – Martin Apr 09 '12 at 17:33
  • It can't work with `const`, since the code uses non-`const` operations on `uc.ref`. Drop the `&` or use C++11 and use `&&`. But Anon's pointer to boost is probably what I'd follow anyway. – Christopher Creutzig Apr 09 '12 at 17:38
  • sorry if I insist, but ref is a reference, not a const reference, so non-const operations should be fine on ref even with a const uppercasify& , shouldn't they? My gcc compiler compiles the above code only if I use a const uppercasify& for operator >> (c++ 98 here) – Martin Apr 09 '12 at 17:57
  • I'm sorry, I forgot that “inheriting” cv-qualifiers does not apply to reference types. (§3.9.3/3, if anyone wants to look it up.) You're right. – Christopher Creutzig Apr 09 '12 at 18:26