Extends std::streambuf to create data buffer : cin « Development « C++ Tutorial






/* The following code example is taken from the book
 * "The C++ Standard Library - A Tutorial and Reference"
 * by Nicolai M. Josuttis, Addison-Wesley, 1999
 *
 * (C) Copyright Nicolai M. Josuttis 1999.
 * Permission to copy, use, modify, sell and distribute this software
 * is granted provided this copyright notice appears in all copies.
 * This software is provided "as is" without express or implied
 * warranty, and with no claim as to its suitability for any purpose.
 */
#include <iostream>

#include <cstdio>
#include <cstring>
#include <streambuf>

// for read():
#ifdef _MSC_VER
# include <io.h>
#else
# include <unistd.h>
#endif

class inbuf : public std::streambuf {
  protected:
    /* data buffer:
     * - at most, four characters in putback area plus
     * - at most, six characters in ordinary read buffer
     */
    static const int bufferSize = 10;    // size of the data buffer
    char buffer[bufferSize];             // data buffer

  public:
    /* constructor
     * - initialize empty data buffer
     * - no putback area
     * => force underflow()
     */
    inbuf() {
        setg (buffer+4,     // beginning of putback area
              buffer+4,     // read position
              buffer+4);    // end position
    }

  protected:
    // insert new characters into the buffer
    virtual int_type underflow () {

        // is read position before end of buffer?
        if (gptr() < egptr()) {
            return traits_type::to_int_type(*gptr());
        }

        /* process size of putback area
         * - use number of characters read
         * - but at most four
         */
        int numPutback;
        numPutback = gptr() - eback();
        if (numPutback > 4) {
            numPutback = 4;
        }

        /* copy up to four characters previously read into
         * the putback buffer (area of first four characters)
         */
        std::memmove (buffer+(4-numPutback), gptr()-numPutback,
                      numPutback);

        // read new characters
        int num;
        num = read (0, buffer+4, bufferSize-4);
        if (num <= 0) {
            // ERROR or EOF
            return EOF;
        }

        // reset buffer pointers
        setg (buffer+(4-numPutback),   // beginning of putback area
              buffer+4,                // read position
              buffer+4+num);           // end of buffer

        // return next character
        return traits_type::to_int_type(*gptr());
    }
};


int main()
{
    inbuf ib;                // create special stream buffer
    std::istream in(&ib);    // initialize input stream with that buffer

    char c;
    for (int i=1; i<=20; i++) {
        // read next character (out of the buffer)
        in.get(c);

        // print that character (and flush)
        std::cout << c << std::flush;

        // after eight characters, put two characters back into the stream
        if (i == 8) {
            in.unget();
            in.unget();
        }
    }
    std::cout << std::endl;
}
a
a
d
d








5.1.cin
5.1.1.Read int value from keyboard
5.1.2.cin Handles Different Data Types
5.1.3.Use get() to read a string that contains spaces
5.1.4.Use the extraction operator >> with cin.get( ) to process an entire string.
5.1.5.cin with strings (cin.getline)
5.1.6.cin and atoi, atof functions
5.1.7.Using peek() and putback()
5.1.8.Concatenate put()
5.1.9.Testing error states.
5.1.10.Unformatted I/O using cin.read, cin.gcount and cout.write
5.1.11.Contrasting input of a string via cin and cin.get
5.1.12.Demonstrating member function width
5.1.13.Read char array from keyboard, get its length and concatenate two strings
5.1.14.Read a character from keyboard
5.1.15.Copy all standard input to standard output
5.1.16.Manipulator that skips until end-of-line
5.1.17.avoids buffer overflow with cin.width
5.1.18.Extends std::streambuf to create data buffer
5.1.19.Using member functions get, put and eof.
5.1.20.Contrasting input of a string with cin and cin.get.
5.1.21.Unformatted I/O with read, gcount and write.
5.1.22.Character input with member function getline.
5.1.23.Is it a bad input