#!/bin/sh # This is a shar archive. # The rest of this file is a shell script which will extract: # # 8_6_alloc.c 8_6_c1.c 8_6_c2.c 8_6_dest.c 8_6_doalloc.c 8_6_fbclose.c 8_6_fbopen.c 8_6_fbover.c 8_6_fbunder.c 8_6_filebuf.h 8_6_init.c 8_6_over.c 8_6_setbuf.c 8_6_sgetc.c 8_6_snextc.c 8_6_spback.c 8_6_sputc.c 8_6_stossc.c 8_6_stream.h 8_6_under.c filebuf.h in.c istream.h main.c makefile ostream.h out.c stream.h streambuf.h tst.c tst.cmp tst.in # # To extract the files from this shell archive file simply # create a directory for this file, move the archive file # to it and enter the command # # sh filename # # The files will be extracted automatically. # Note: Do not use csh. # # Archive created: Mon Jul 30 23:13:26 EDT 1990 # echo x - 8_6_alloc.c sed 's/^X//' > 8_6_alloc.c << '!EOF!' /* Copyright (c) 1990 by AT&T Bell Telephone Laboratories, Incorporated. */ /* The C++ Answer Book */ /* Tony Hansen */ /* All rights reserved. */ // Do a quick check to see if the // buffer needs to be allocated. // inline int streambuf::allocate() { return base ? 0 : doallocate(); } !EOF! ls -l 8_6_alloc.c echo x - 8_6_c1.c sed 's/^X//' > 8_6_c1.c << '!EOF!' /* Copyright (c) 1990 by AT&T Bell Telephone Laboratories, Incorporated. */ /* The C++ Answer Book */ /* Tony Hansen */ /* All rights reserved. */ // inline streambuf::streambuf() { base = gptr = pptr = eptr = 0; alloc = 0; } !EOF! ls -l 8_6_c1.c echo x - 8_6_c2.c sed 's/^X//' > 8_6_c2.c << '!EOF!' /* Copyright (c) 1990 by AT&T Bell Telephone Laboratories, Incorporated. */ /* The C++ Answer Book */ /* Tony Hansen */ /* All rights reserved. */ // inline streambuf::streambuf(char* buf, int len) { setbuf(buf, len); } !EOF! ls -l 8_6_c2.c echo x - 8_6_dest.c sed 's/^X//' > 8_6_dest.c << '!EOF!' /* Copyright (c) 1990 by AT&T Bell Telephone Laboratories, Incorporated. */ /* The C++ Answer Book */ /* Tony Hansen */ /* All rights reserved. */ // inline streambuf::~streambuf() { if (alloc) delete base; } !EOF! ls -l 8_6_dest.c echo x - 8_6_doalloc.c sed 's/^X//' > 8_6_doalloc.c << '!EOF!' /* Copyright (c) 1990 by AT&T Bell Telephone Laboratories, Incorporated. */ /* The C++ Answer Book */ /* Tony Hansen */ /* All rights reserved. */ // allocate some space for the buffer int streambuf::doallocate() { base = new char[BUFSIZ]; if (!base) return EOF; setbuf(base, BUFSIZ); alloc = 1; return 0; } !EOF! ls -l 8_6_doalloc.c echo x - 8_6_fbclose.c sed 's/^X//' > 8_6_fbclose.c << '!EOF!' /* Copyright (c) 1990 by AT&T Bell Telephone Laboratories, Incorporated. */ /* The C++ Answer Book */ /* Tony Hansen */ /* All rights reserved. */ // Close the file // inline int filebuf::close() { int ret = opened ? fclose(fp) : 0; opened = 0; return ret; } !EOF! ls -l 8_6_fbclose.c echo x - 8_6_fbopen.c sed 's/^X//' > 8_6_fbopen.c << '!EOF!' /* Copyright (c) 1990 by AT&T Bell Telephone Laboratories, Incorporated. */ /* The C++ Answer Book */ /* Tony Hansen */ /* All rights reserved. */ // Open a file with the given mode. filebuf* filebuf::open (const char *name, open_mode om) { fp = fopen(name, (om == input) ? "r" : (om == output) ? "w" : "a"); if (!fp) return 0; opened = 1; return this; } !EOF! ls -l 8_6_fbopen.c echo x - 8_6_fbover.c sed 's/^X//' > 8_6_fbover.c << '!EOF!' /* Copyright (c) 1990 by AT&T Bell Telephone Laboratories, Incorporated. */ /* The C++ Answer Book */ /* Tony Hansen */ /* All rights reserved. */ // Empty an output buffer. #include int filebuf::overflow(int c) { if (!opened || allocate() == EOF) return EOF; // unbuffered IO if (base == eptr) { if (c != EOF) { *pptr = c; if (putc(c, fp) != c) return EOF; } } // buffered IO else { if (pptr > base) if (fwrite(base, sizeof(char), pptr-base, fp) != pptr-base) return EOF; // reset the pointers and store the character pptr = gptr = base; if (c != EOF) *pptr++ = c; } return (c & UCHAR_MAX); } !EOF! ls -l 8_6_fbover.c echo x - 8_6_fbunder.c sed 's/^X//' > 8_6_fbunder.c << '!EOF!' /* Copyright (c) 1990 by AT&T Bell Telephone Laboratories, Incorporated. */ /* The C++ Answer Book */ /* Tony Hansen */ /* All rights reserved. */ // Fill a buffer using fread. // Return the next character or EOF // on the end of the input or an error. #include int filebuf::underflow() { if (!opened || allocate() == EOF) return EOF; int count = fread(base, sizeof(char), eptr - base, fp); if (count < 1) return EOF; gptr = base; pptr = base + count; return (*gptr & UCHAR_MAX); } !EOF! ls -l 8_6_fbunder.c echo x - 8_6_filebuf.h sed 's/^X//' > 8_6_filebuf.h << '!EOF!' /* Copyright (c) 1990 by AT&T Bell Telephone Laboratories, Incorporated. */ /* The C++ Answer Book */ /* Tony Hansen */ /* All rights reserved. */ // a streambuf tied to a file via stdio class filebuf : public streambuf { FILE *fp; // stdio file pointer char opened; // mode of file public: int overflow(int c = EOF); int underflow(); // open a file and return 0 on failure filebuf *open(const char *name, open_mode m); int close(); filebuf() { opened = 0; fp = 0; } // tie to already opened file filebuf(FILE *nfp) { opened = 1; fp = nfp; } // tie to already opened file // using the given buffer filebuf(FILE *nfp, char *buf, int len) : (buf, len) { opened = 1; fp = nfp; } ~filebuf() { close(); } }; !EOF! ls -l 8_6_filebuf.h echo x - 8_6_init.c sed 's/^X//' > 8_6_init.c << '!EOF!' /* Copyright (c) 1990 by AT&T Bell Telephone Laboratories, Incorporated. */ /* The C++ Answer Book */ /* Tony Hansen */ /* All rights reserved. */ // declare a suitable amount of buffer space for cout static char cout_buf[BUFSIZ]; // Make a filebuf to manage that space. // Bind it to the UNIX FILE pointer stdout static filebuf cout_file (stdout, cout_buf, sizeof(cout_buf)); // make the ostream providing the user interface ostream cout(&cout_file); // declare a suitable amount of buffer space for cerr static char cerr_buf[1]; // Make a filebuf to manage that space. // Bind it to the UNIX FILE pointer stderr static filebuf cerr_file (stderr, cerr_buf, sizeof(cerr_buf)); ostream cerr(&cerr_file); // declare a suitable amount of buffer space for cin static char cin_buf[BUFSIZ]; // Make a filebuf to manage that space. // Bind it to the UNIX FILE pointer stdin static filebuf cin_file (stdin, cin_buf, sizeof(cin_buf)); // make the istream providing the user interface istream cin(&cin_file); !EOF! ls -l 8_6_init.c echo x - 8_6_over.c sed 's/^X//' > 8_6_over.c << '!EOF!' /* Copyright (c) 1990 by AT&T Bell Telephone Laboratories, Incorporated. */ /* The C++ Answer Book */ /* Tony Hansen */ /* All rights reserved. */ // Handle both an uninitialized and a full buffer. #include int streambuf::overflow(int c) { if (allocate() == EOF) return EOF; if ((c != EOF) && (pptr < eptr)) *pptr++ = c; return c & UCHAR_MAX; } !EOF! ls -l 8_6_over.c echo x - 8_6_setbuf.c sed 's/^X//' > 8_6_setbuf.c << '!EOF!' /* Copyright (c) 1990 by AT&T Bell Telephone Laboratories, Incorporated. */ /* The C++ Answer Book */ /* Tony Hansen */ /* All rights reserved. */ // Supply a character array for a buffer. // inline streambuf * streambuf::setbuf(char *buf, int len, int startlen) { base = gptr = buf; pptr = buf + startlen; eptr = base + len; alloc = 0; return this; } !EOF! ls -l 8_6_setbuf.c echo x - 8_6_sgetc.c sed 's/^X//' > 8_6_sgetc.c << '!EOF!' /* Copyright (c) 1990 by AT&T Bell Telephone Laboratories, Incorporated. */ /* The C++ Answer Book */ /* Tony Hansen */ /* All rights reserved. */ // get the current character #include // inline int streambuf::sgetc() { return (gptr >= pptr) ? underflow() : (*gptr & UCHAR_MAX); } !EOF! ls -l 8_6_sgetc.c echo x - 8_6_snextc.c sed 's/^X//' > 8_6_snextc.c << '!EOF!' /* Copyright (c) 1990 by AT&T Bell Telephone Laboratories, Incorporated. */ /* The C++ Answer Book */ /* Tony Hansen */ /* All rights reserved. */ // get the next character #include // inline int streambuf::snextc() { return (gptr >= (pptr - 1)) ? underflow() : (*++gptr & UCHAR_MAX); } !EOF! ls -l 8_6_snextc.c echo x - 8_6_spback.c sed 's/^X//' > 8_6_spback.c << '!EOF!' /* Copyright (c) 1990 by AT&T Bell Telephone Laboratories, Incorporated. */ /* The C++ Answer Book */ /* Tony Hansen */ /* All rights reserved. */ // inline void streambuf::sputbackc(char c) { if (gptr > base) *--gptr = c; } !EOF! ls -l 8_6_spback.c echo x - 8_6_sputc.c sed 's/^X//' > 8_6_sputc.c << '!EOF!' /* Copyright (c) 1990 by AT&T Bell Telephone Laboratories, Incorporated. */ /* The C++ Answer Book */ /* Tony Hansen */ /* All rights reserved. */ // put a character into the buffer #include // inline int streambuf::sputc(int c) { return (eptr <= pptr) ? overflow(c & UCHAR_MAX) : (*pptr++ = c & UCHAR_MAX); } !EOF! ls -l 8_6_sputc.c echo x - 8_6_stossc.c sed 's/^X//' > 8_6_stossc.c << '!EOF!' /* Copyright (c) 1990 by AT&T Bell Telephone Laboratories, Incorporated. */ /* The C++ Answer Book */ /* Tony Hansen */ /* All rights reserved. */ // advance to the next character // inline void streambuf::stossc() { if (gptr++ >= pptr) underflow(); } !EOF! ls -l 8_6_stossc.c echo x - 8_6_stream.h sed 's/^X//' > 8_6_stream.h << '!EOF!' /* Copyright (c) 1990 by AT&T Bell Telephone Laboratories, Incorporated. */ /* The C++ Answer Book */ /* Tony Hansen */ /* All rights reserved. */ // Exercise 8.6 // // Implementation of stream I/O // using the standard I/O functions. #ifndef STREAMBUF_H #define STREAMBUF_H // a buffer for streams class streambuf { char alloc; // buffer was allocated friend filebuf; protected: char *base; // beginning of buffer char *pptr; // next free byte char *gptr; // next filled byte char *eptr; // first byte following buffer // allocate some space for the buffer int doallocate(); public: streambuf(); streambuf(char* p, int l); ~streambuf(); // Empty the buffer. Return EOF on error, // 0 on success. virtual int overflow(int c = EOF); // Fill a buffer. Return EOF on error // or end of input, else the next character virtual int underflow(); // get the current character or EOF int sgetc(); // get the next character int snextc(); // advance to the next character void stossc(); // Return a character to the buffer. void sputbackc(char c); // put a character into the buffer int sputc(int c = EOF); // supply an area for a buffer. streambuf *setbuf(char *p, int len, int count =0); // check the buffer and allocate if necessary int allocate(); }; #endif /* STREAMBUF_H */ !EOF! ls -l 8_6_stream.h echo x - 8_6_under.c sed 's/^X//' > 8_6_under.c << '!EOF!' /* Copyright (c) 1990 by AT&T Bell Telephone Laboratories, Incorporated. */ /* The C++ Answer Book */ /* Tony Hansen */ /* All rights reserved. */ // Fill a buffer. Return the next character // or EOF on the end of the input or an error. // inline int streambuf::underflow() { return EOF; } !EOF! ls -l 8_6_under.c echo x - filebuf.h sed 's/^X//' > filebuf.h << '!EOF!' /* Copyright (c) 1990 by AT&T Bell Telephone Laboratories, Incorporated. */ /* The C++ Answer Book */ /* Tony Hansen */ /* All rights reserved. */ #include "8_6_filebuf.h" !EOF! ls -l filebuf.h echo x - in.c sed 's/^X//' > in.c << '!EOF!' /* Copyright (c) 1990 by AT&T Bell Telephone Laboratories, Incorporated. */ /* The C++ Answer Book */ /* Tony Hansen */ /* All rights reserved. */ /*ident "@(#)cfront:lib/stream/in.c 1.8" */ /* C++ stream i/o source in.c */ #include #include // #include /* predefined whitespace */ whitespace WS; // inline void eatwhite (istream& is) { if (is.tied_to) is.tied_to->flush(); register streambuf *nbp = is.bp; register c = nbp->sgetc(); while (isspace(c&0377)) c = nbp->snextc(); if (c == EOF) is.state |= _eof; } istream& istream::operator>>(whitespace&) { register streambuf *nbp = bp; if (state) return *this; if (tied_to) tied_to->flush(); register c = nbp->sgetc(); while (isspace(c)) c = nbp->snextc(); if (c == EOF) state |= _eof; return *this; } istream& istream::operator>>(register char& s) /* reads characters NOT very small integers */ { if (skipws) eatwhite(*this); else if (tied_to) tied_to->flush(); if (state) { state |= _fail; return *this; } register c = bp->sgetc(); if (c == EOF) { state |= _fail|_eof; } else { s = c; bp->stossc(); } return *this; } istream& istream::operator>>(register char* s) { register streambuf *nbp = bp; if (skipws) eatwhite(*this); else if (tied_to) tied_to->flush(); if (state) { state |= _fail; return *this; } /* get string */ register c = nbp->sgetc(); if (c == EOF) state |= _fail; while (!isspace(c) && c != EOF) { *s++ = c; c = nbp->snextc(); } *s = '\0'; if (c == EOF) state |= _eof; return *this; } istream& istream::operator>>(long& i) { register c; register ii = 0; register streambuf *nbp = bp; int neg = 0; if (skipws) eatwhite(*this); else if (tied_to) tied_to->flush(); if (state) { state |= _fail; return *this; } switch (c = nbp->sgetc()) { case '-': case '+': neg = c; c = nbp->snextc(); break; case EOF: state |= _fail; } if (isdigit(c)) { do { ii = ii*10+c-'0'; } while (isdigit(c=nbp->snextc())); i = (neg=='-') ? -ii : ii; } else state |= _fail; if (c == EOF) state |= _eof; return *this; } istream& istream::operator>>(int& i) { long l; if (skipws) eatwhite(*this); else if (tied_to) tied_to->flush(); if (state) { state |= _fail; return *this; } if ( *this>>l ) { i = (int)l; } return *this; } istream& istream::operator>>(short& i) { long l; if (skipws) eatwhite(*this); else if (tied_to) tied_to->flush(); if (state) { state |= _fail; return *this; } if ( *this>>l ) { i = (short)l; } return *this; } istream& istream::operator>>(double& d) /* {+|-} d* {.} d* { e|E {+|-} d+ } except that - a dot must be pre- or succeded by at least one digit - an exponent must be preseded by at least one digit */ { register c = 0; char buf[256]; register char* p = buf; register streambuf* nbp = bp; if (skipws) eatwhite(*this); else if (tied_to) tied_to->flush(); if (state) { state |= _fail; return *this; } /* get the sign */ switch (c = nbp->sgetc()) { case EOF: state = _eof|_fail; return *this; case '-': case '+': *p++ = c; c = bp->snextc(); } /* get integral part */ while (isdigit(c)) { *p++ = c; c = bp->snextc(); } /* get fraction */ if (c == '.') { do { *p++ = c; c = bp->snextc(); } while (isdigit(c)); } /* get exponent */ if (c == 'e' || c == 'E') { *p++ = c; switch (c = nbp->snextc()) { case EOF: state = _eof|_fail; return *this; case '-': case '+': *p++ = c; c = bp->snextc(); } while (isdigit(c)) { *p++ = c; c = bp->snextc(); } } *p = 0; d = atof(buf); if (c == EOF) state |= _eof; return *this; } istream& istream::operator>>(float& f) { double d; if (skipws) eatwhite(*this); else if (tied_to) tied_to->flush(); if (state) { state |= _fail; return *this; } if ( *this>>d ) { f = d; } return *this; } istream& istream::get( register char* s, /* character array to read into */ register int len, /* size of character array */ register char term /* character that terminates input */ ) { register c; register streambuf *nbp = bp; if (tied_to) tied_to->flush(); if (state) { state |= _fail; return *this; } if ((c = bp->sgetc()) == EOF) { state |= _fail | _eof; return *this; } while (c != term && c != EOF && len > 1) { *s++ = c; c = nbp->snextc(); len--; } *s = '\0'; if (c == EOF) state |= _eof; return *this; } istream& istream::putback(register char c) { bp->sputbackc(c); return *this; } istream& istream::get( register streambuf &s, /* streambuf to input to */ register char term /* termination character */ ) { register c; register streambuf *nbp = bp; if (tied_to) tied_to->flush(); if (state) { state |= _fail; return *this; } if ((c = bp->sgetc()) == EOF) { state |= _fail | _eof; return *this; } while (c != term && c != EOF) { if (s.sputc(c) == EOF) break; c = nbp->snextc(); } if (c == EOF) state |= _eof; return *this; } istream& istream::operator>>(register streambuf &s) { register c; register streambuf *nbp = bp; if (tied_to) tied_to->flush(); if (state) { state |= _fail; return *this; } if ((c = bp->sgetc()) == EOF) { state |= _fail | _eof; return *this; } while (c != EOF) { if (s.sputc(c) == EOF) break; c = nbp->snextc(); } if (c == EOF) state |= _eof; return *this; } //istream& istream::operator>>(common& p) //{ // if (skipws) // eatwhite(*this); // else if (tied_to) // tied_to->flush(); // // return p.read(*this); //} !EOF! ls -l in.c echo x - istream.h sed 's/^X//' > istream.h << '!EOF!' /* Copyright (c) 1990 by AT&T Bell Telephone Laboratories, Incorporated. */ /* The C++ Answer Book */ /* Tony Hansen */ /* All rights reserved. */ class istream { friend ostream; streambuf* bp; ostream* tied_to; char skipws; // if non-null, automaticly skip whitespace short state; friend void eatwhite (istream&); public: int skip(int i) { int ii=skipws; skipws=i; return ii; } /* formatted input: >> skip whitespace */ istream& operator>>(char*); // string istream& operator>>(char&); // single character istream& operator>>(short&); istream& operator>>(int&); istream& operator>>(long&); istream& operator>>(float&); istream& operator>>(double&); istream& operator>>(streambuf&); istream& operator>>(whitespace&); // skip whitespace // istream& operator>>(common&); /* raw input: get's do not skip whitespace */ istream& get(char*, int, char ='\n'); // string istream& get(streambuf& sb, char ='\n'); istream& get(char& c) // single character { int os = skipws; skipws = 0; *this >> c; skipws = os; return *this; } istream& putback(char c); ostream* tie(ostream* s) { ostream* t = tied_to; tied_to = s; return t; } operator void*(){ return _eofbase; } istream(streambuf* s, int sk =1, ostream* t =0) // bind to buffer { state = 0; skipws = sk; tied_to = t; bp = s; } istream(int size, char* p, int sk =1) // bind to string { state = 0; skipws = sk; tied_to = 0; bp = new streambuf(); if (p == 0) p = new char[size]; bp->setbuf(p, size, size); } istream(FILE *fp, int sk =1, ostream* t =0) // bind to file { state = 0; skipws = sk; tied_to = t; bp = new filebuf(fp); } }; !EOF! ls -l istream.h echo x - main.c sed 's/^X//' > main.c << '!EOF!' /* Copyright (c) 1990 by AT&T Bell Telephone Laboratories, Incorporated. */ /* The C++ Answer Book */ /* Tony Hansen */ /* All rights reserved. */ #include main() { int a; double d; cin >> a; cin >> d; cout << "a = " << a << "\n"; cout << "d = " << d << "\n"; return 0; } !EOF! ls -l main.c echo x - makefile sed 's/^X//' > makefile << '!EOF!' CC= CC -I. -I../../CC CFLAGS= all: tst tst: tst.o in.o out.o main.o $(CC) tst.o in.o out.o main.o -o tst tst.o: 8_6_filebuf.h 8_6_stream.h istream.h ostream.h stream.h 8_6_alloc.c 8_6_c1.c 8_6_c2.c 8_6_dest.c 8_6_doalloc.c 8_6_fbclose.c 8_6_fbopen.c 8_6_fbover.c 8_6_fbunder.c 8_6_init.c 8_6_over.c 8_6_setbuf.c 8_6_sgetc.c 8_6_snextc.c 8_6_spback.c 8_6_sputc.c 8_6_stossc.c 8_6_under.c tst.c $(CC) $(CFLAGS) -c tst.c in.o: in.c 8_6_filebuf.h 8_6_stream.h filebuf.h istream.h ostream.h stream.h streambuf.h $(CC) $(CFLAGS) -c in.c out.o: out.c 8_6_filebuf.h 8_6_stream.h filebuf.h istream.h ostream.h stream.h streambuf.h $(CC) $(CFLAGS) -c out.c main.o: main.c 8_6_filebuf.h 8_6_stream.h filebuf.h istream.h ostream.h stream.h streambuf.h $(CC) $(CFLAGS) -c main.c CMP= tst.cmp OUT= tst.out tst.out: tst tst.in ; tst < tst.in > tst.out test: $(CMP) $(OUT) cmp tst.out tst.cmp @echo test done !EOF! ls -l makefile echo x - ostream.h sed 's/^X//' > ostream.h << '!EOF!' /* Copyright (c) 1990 by AT&T Bell Telephone Laboratories, Incorporated. */ /* The C++ Answer Book */ /* Tony Hansen */ /* All rights reserved. */ class ostream { friend istream; streambuf *bp; state_value state; public: ostream& operator<<(const char*); // write ostream& operator<<(int a) { return *this<overflow(); return *this; } operator void*(){ return _eofbase; } ostream(streambuf* s) { bp = s; state = 0; } ostream(FILE *fp) { bp = new filebuf(fp); state = 0; } ostream(int size, char* p) { state = 0; bp = new streambuf(); if (p == 0) p = new char[size]; bp->setbuf(p, size); } ~ostream() { flush(); } }; !EOF! ls -l ostream.h echo x - out.c sed 's/^X//' > out.c << '!EOF!' /* Copyright (c) 1990 by AT&T Bell Telephone Laboratories, Incorporated. */ /* The C++ Answer Book */ /* Tony Hansen */ /* All rights reserved. */ /*ident "@(#)cfront:lib/stream/out.c 1.6" */ /* C++ stream i/o source out.c */ #include #include #define MAXOSTREAMS 20 const cb_size = 1024; const fld_size = 256; /* a circular formating buffer */ static char formbuf[cb_size]; // some slob for form overflow static char* bfree=formbuf; static char* max = &formbuf[cb_size-1]; char* chr(register i, register int w) /* note: chr(0) is "" */ { register char* buf = bfree; if (w<=0 || fld_size>=4)); while (0>=4); } return p+1; } char* oct(long ii, int w) { int m = sizeof(long)*3; // maximum oct digits for a long if (w<0 || fld_size>=3)); while (0>=3); } return p+1; } char* dec(long i, int w) { int sign = 0; if (i < 0) { sign = 1; i = -i; } int m = sizeof(long)*3; /* maximum dec digits for a long */ if (w<0 || fld_sizesputc(*s++) == EOF) { state |= _eof|_fail; break; } while (*s); return *this; } ostream& ostream::operator<<(unsigned long i) { register streambuf* nbp = bp; char buf[32]; register char *p = buf; if (state) return *this; do { *p++ = '0' + int(i%10); i = i/10; } while (i > 0); do { if (nbp->sputc(*--p) == EOF) { state |= _fail | _eof; break; } } while (p != buf); return *this; } ostream& ostream::operator<<(long i) { register streambuf* nbp = bp; register long j; char buf[32]; register char *p = buf; if (state) return *this; if (i < 0) { nbp->sputc('-'); j = -i; } else j = i; do { *p++ = '0' + char(j%10); j = j/10; } while (j > 0); do { if (nbp->sputc(*--p) == EOF) { state |= _fail | _eof; break; } } while (p != buf); return *this; } ostream& ostream::put(char c) { if (state) return *this; if (bp->sputc(c) == EOF) state |= _eof|_fail; return *this; } ostream& ostream::operator<<(double d) { register streambuf* nbp = bp; char buf[32]; register char *p = buf; if (state) return *this; sprintf(buf,"%g",d); while (*p != '\0') if (nbp->sputc(*p++) == EOF) { state |= _eof|_fail; break; } return *this; } ostream& ostream::operator<<(const streambuf& b) { register streambuf* nbp = bp; register int c; if (state) return *this; c = b.sgetc(); while (c != EOF) { if (nbp->sputc(c) == EOF) { state |= _eof|_fail; break; } c = b.snextc(); } return *this; } !EOF! ls -l out.c echo x - stream.h sed 's/^X//' > stream.h << '!EOF!' /* Copyright (c) 1990 by AT&T Bell Telephone Laboratories, Incorporated. */ /* The C++ Answer Book */ /* Tony Hansen */ /* All rights reserved. */ // Exercise 8.6 // // Implementation of stream I/O // using the standard I/O functions. #ifndef STREAM_H #define STREAM_H #define istream xistream /* DELETE */ #define ostream xostream /* DELETE */ #define filebuf xfilebuf /* DELETE */ #define streambuf xstreambuf /* DELETE */ #define cout xcout /* DELETE */ #define cin xcin /* DELETE */ #define cerr xcerr /* DELETE */ class istream; class ostream; // class common; enum state_value { _good=0, _eof=1, _fail=2, _bad=4 }; enum open_mode { input=0, output=1, append=2 }; struct whitespace { }; #include #include #include #include #include extern ostream cout, cerr; extern istream cin; #endif /* STREAM_H */ !EOF! ls -l stream.h echo x - streambuf.h sed 's/^X//' > streambuf.h << '!EOF!' /* Copyright (c) 1990 by AT&T Bell Telephone Laboratories, Incorporated. */ /* The C++ Answer Book */ /* Tony Hansen */ /* All rights reserved. */ #include "8_6_stream.h" !EOF! ls -l streambuf.h echo x - tst.c sed 's/^X//' > tst.c << '!EOF!' /* Copyright (c) 1990 by AT&T Bell Telephone Laboratories, Incorporated. */ /* The C++ Answer Book */ /* Tony Hansen */ /* All rights reserved. */ #include #include "8_6_alloc.c" #include "8_6_c1.c" #include "8_6_c2.c" #include "8_6_dest.c" #include "8_6_doalloc.c" #include "8_6_fbclose.c" #include "8_6_fbopen.c" #include "8_6_fbover.c" #include "8_6_fbunder.c" #include "8_6_init.c" #include "8_6_over.c" #include "8_6_setbuf.c" #include "8_6_sgetc.c" #include "8_6_snextc.c" #include "8_6_spback.c" #include "8_6_sputc.c" #include "8_6_stossc.c" #include "8_6_under.c" !EOF! ls -l tst.c echo x - tst.cmp sed 's/^X//' > tst.cmp << '!EOF!' a = 2341 d = 3251.23 !EOF! ls -l tst.cmp echo x - tst.in sed 's/^X//' > tst.in << '!EOF!' 2341 3251.2341 !EOF! ls -l tst.in # The following exit is to ensure that extra garbage # after the end of the shar file will be ignored. exit 0