9.5 Manipulators

   

A manipulator is a function object that can be used as an operand to an input or output operator to manipulate the stream. Manipulators can send additional output to a stream, read input from a stream, set flags, and more. For example, to output a zero- padded , hexadecimal integer, you can use an ostream 's member functions or manipulators, whichever you prefer. Example 9-7 shows both ways.

Example 9-7. Manipulating an output stream to format a number
 using namespace std; // Output a value using ostream's member functions. cout.fill('0'); cout.width(8); cout.setf(ios_base::internal, ios_base::adjustfield); cout.setf(ios_base::hex, ios_base::basefield); cout << value; // Output the same value using manipulators. cout << setfill('0') << setw(8) << hex << internal << value; 

9.5.1 Standard Manipulators

The standard library defines several manipulators for setting formatting flags, setting other formatting parameters, skipping whitespace, flushing output, and more. The following is a list of all the standard manipulators, grouped by header:

<ios>

Declares the manipulators that set the formatting flags: boolalpha , dec , fixed , hex , internal , left , noboolalpha , noshowbase , noshowpoint , noshowpos , noskipws , nouppercase , nounitbuf , oct , right , scientific , showbase , showpoint , showpos , skipws , uppercase , and unitbuf

<istream>

Declares the input manipulator: ws

<ostream>

Declares the output manipulators: endl , ends , and flush

<iomanip>

Declares several additional manipulators: resetioflags , setioflags , setbase , setfill , setprecision , and setw

Most manipulators are declared in the same header as the stream type they manipulate. The only time you need to #include an additional header is when you use a manipulator that takes an argument. These manipulators are in the <iomanip> header.

9.5.2 Custom Manipulators

To write your own manipulator, use the standard manipulators as patterns. The easiest to use are manipulators that take no arguments. A manipulator is simply a function that takes a stream as an argument and returns the same stream. The standard streams overload operator<< and operator>> to take a pointer to such a function as an operand.

Suppose you want to write an input manipulator that skips all characters up to and including a newline. (Perhaps this manipulator is used by a command processor after reading a // comment sequence.) Example 9-8 shows one way to write the skipline manipulator.

Example 9-8. Skipping a line in an input stream
 template<typename charT, typename traits> std::basic_istream<charT,traits>& skipline(std::basic_istream<charT,traits>& in) {   charT c;   while (in.get(c) && c != '\n')     ;   return in; } ... int x; std::string next; std::cin >> x >> skipline >> next; 

Manipulators that take arguments are harder to write, but only slightly. You need to write some supporting infrastructure, such as additional overloaded operator>> or operator<< functions.

For example, suppose you want to parameterize your input skipline manipulator so it skips everything up to a caller-supplied character. This manipulator is defined as a class template, in which the constructor takes the manipulator's argument, that is, the delimiter character. You must overload operator>> so it recognizes your manipulator as an operand and invokes the manipulator's operator( ) . You don't need to use operator( ) , but this is a good choice when building a reusable infrastructure for manipulators. Example 9-9 shows the new skip manipulator.

Example 9-9. Writing a manipulator that takes an argument
 template<typename charT> class skipper { public:   typedef charT char_type;   skipper(char_type delim) : delim_(delim) {}   template<typename traits>   void operator(  )(std::basic_istream<charT,traits>&) const; private:   char_type delim_; }; // Skip the rest of the line. The compiler deduces the traits type from the // stream argument. template<typename charT> template<typename traits> void skipper<charT>::operator(  )(std::basic_istream<charT,traits>& stream) const {   char_type c;   while (stream.get(c) && c != delim_)     ; } // Invoke the skipper manipulator. template<typename charT, typename traits> std::basic_istream<charT,traits>&             const skipper<charT>& f) {   f(stream);   return stream; } // Let the compiler deduce the character type. template<typename charT> skipper<charT> skip(charT c) {   return skipper<charT>(c); } ... int x; std::string next; std::cin >> x >> skip('\n') >> next; 
   


C++ in a Nutshell
C++ in a Nutshell
ISBN: 059600298X
EAN: 2147483647
Year: 2005
Pages: 270
Authors: Ray Lischner

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net