/* 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. */ #if 0 ////////// io/io1.cpp p587 #include #include using namespace std; int main() { double x, y; // operands // print header string cout << "Multiplication of two floating point values" << endl; // read first operand cout << "first operand: "; if (! (cin >> x)) { /* input error * => error message and exit program with error status */ cerr << "error while reading the first floating value" << endl; return EXIT_FAILURE; } // read second operand cout << "second operand: "; if (! (cin >> y)) { /* input error * => error message and exit program with error status */ cerr << "error while reading the second floating value" << endl; return EXIT_FAILURE; } // print operands and result cout << x << " times " << y << " equals " << x * y << endl; return EXIT_SUCCESS; } // Multiplication of two floating point values // first operand: 9 // second operand: 11 // 9 times 11 equals 99 ////////// io/sum1.cpp p605, p603 #include #include namespace MyLib { double readAndProcessSum (std::istream&); } int main() { using namespace std; double sum; try { sum = MyLib::readAndProcessSum(cin); } catch (const ios::failure& error) { cerr << "I/O exception: " << error.what() << endl; return EXIT_FAILURE; } catch (const exception& error) { cerr << "standard exception: " << error.what() << endl; return EXIT_FAILURE; } catch (...) { cerr << "unknown exception" << endl; return EXIT_FAILURE; } // print sum cout << "sum: " << sum << endl; return EXIT_SUCCESS; } #include namespace MyLib { double readAndProcessSum (std::istream& strm) { using std::ios; double value, sum; // save current state of exception flags ios::iostate oldExceptions = strm.exceptions(); /* let failbit and badbit throw exceptions * - NOTE: failbit is also set at end-of-file */ strm.exceptions (ios::failbit | ios::badbit); try { /* while stream is OK * - read value and add it to sum */ sum = 0; while (strm >> value) { sum += value; } } catch (...) { /* if exception not caused by end-of-file * - restore old state of exception flags * - rethrow exception */ if (!strm.eof()) { strm.exceptions(oldExceptions); // restore exception flags throw; // rethrow } } // restore old state of exception flags strm.exceptions (oldExceptions); // return sum return sum; } } // 1 2 3 4 5 // ^Z // ^Z // sum: 15 // 1 2 3 4 a // I/O exception: ios::failbit set ////////// io/sum2.cpp p605, p606 #include #include namespace MyLib { double readAndProcessSum (std::istream&); } int main() { using namespace std; double sum; try { sum = MyLib::readAndProcessSum(cin); } catch (const ios::failure& error) { cerr << "I/O exception: " << error.what() << endl; return EXIT_FAILURE; } catch (const exception& error) { cerr << "standard exception: " << error.what() << endl; return EXIT_FAILURE; } catch (...) { cerr << "unknown exception" << endl; return EXIT_FAILURE; } // print sum cout << "sum: " << sum << endl; return EXIT_SUCCESS; } #include namespace MyLib { double readAndProcessSum (std::istream& strm) { double value, sum; /* while stream is OK * - read value and add it to sum */ sum = 0; while (strm >> value) { sum += value; } if (!strm.eof()) { throw std::ios::failure ("input error in readAndProcessSum()"); } // return sum return sum; } } ////////// io/charcat1.cpp p611 #include using namespace std; int main() { char c; // while it is possible to read a character while (cin.get(c)) { // print it cout.put(c); } return EXIT_SUCCESS; } // now is the time // now is the time // for all good men // for all good men // ^Z ////////// io/ignore1.cpp p614 #include /********* #include "ignore.hpp" *********/ #include #include template inline std::basic_istream& ignoreLine (std::basic_istream& strm) { // skip until end-of-line strm.ignore(std::numeric_limits::max(),strm.widen('\n')); // return stream for concatenation return strm; } /********* #include "ignore.hpp" *********/ int main() { int i; std::cout << "read int and ignore rest of the line" << std::endl; std::cin >> i; // ignore the rest of the line std::cin >> ignoreLine; std::cout << "int: " << i << std::endl; std::cout << "read int and ignore two lines" << std::endl; std::cin >> i; // ignore two lines std::cin >> ignoreLine >> ignoreLine; std::cout << "int: " << i << std::endl; return EXIT_SUCCESS; } // read int and ignore rest of the line // 12321 the quick brown fox // int: 12321 // read int and ignore two lines // 2468 line one // line two // int: 2468 ////////// io/charset.cpp p629 #include // for strings #include // for I/O #include // for file I/O #include // for setw() #include // for exit() using namespace std; // forward declarations void writeCharsetToFile (const string& filename); void outputFile (const string& filename); int main () { writeCharsetToFile("charset.out"); outputFile("charset.out"); return EXIT_SUCCESS; } void writeCharsetToFile (const string& filename) { // open output file ofstream file(filename.c_str()); // file opened? if (! file) { // NO, abort program cerr << "can't open output file \"" << filename << "\"" << endl; exit(EXIT_FAILURE); } // write character set for (int i=32; i<256; i++) { file << "value: " << setw(3) << i << " " << "char: " << static_cast(i) << endl; } } // closes file automatically void outputFile (const string& filename) { // open input file ifstream file(filename.c_str()); // file opened? if (! file) { // NO, abort program cerr << "can't open input file \"" << filename << "\"" << endl; exit(EXIT_FAILURE); } // copy file contents to cout char c; while (file.get(c)) { cout.put(c); } } // closes file automatically // value: 32 char: // value: 33 char: ! // value: 34 char: " // value: 35 char: # // value: 36 char: $ // value: 37 char: % // value: 38 char: & // value: 39 char: ' // value: 40 char: ( // value: 41 char: ) // value: 42 char: * // value: 43 char: + // value: 44 char: , // value: 45 char: - // value: 46 char: . // value: 47 char: / // value: 48 char: 0 // value: 49 char: 1 // ... // D:\projects\AdvCpp\Debug> dir /od // 03/10/2001 01:24p 5,152 charset.out ////////// io/cat1.cpp p633 #include #include using namespace std; /* for all file names passed as command-line arguments * - open, print contents, and close file */ int main (int argc, char* argv[]) { ifstream file; // for all command-line arguments for (int i=1; i advcpp one.txt two.txt // one.txt // line one // last two // two.txt // first line // last line ////////// io/cat2.cpp p636 #include #include void printFileTwice (const char* filename) { // open file std::ifstream file(filename); // print contents the first time std::cout << file.rdbuf(); // seek to the beginning file.seekg(0); // print contents the second time std::cout << file.rdbuf(); } int main (int argc, char* argv[]) { // print all files passed as a command-line argument twice for (int i=1; i advcpp one.txt two.txt // one.txt // line one // last two // one.txt // line one // last two // two.txt // first line // last line // two.txt // first line // last line ////////// io/rdbuf1.cpp p639 #include #include using namespace std; int main() { // stream for hexadecimal standard output ostream hexout(cout.rdbuf()); hexout.setf (ios::hex, ios::basefield); hexout.setf (ios::showbase); // switch between decimal and hexadecimal output hexout << "hexout: " << 177 << " "; cout << "cout: " << 177 << " "; hexout << endl; hexout << "hexout: " << -49 << " "; cout << "cout: " << -49 << " "; hexout << endl; return EXIT_SUCCESS; } // hexout: 0xb1 cout: 177 // hexout: 0xffffffcf cout: -49 ////////// io/rdbuf2.cpp p639 #include #include void hexMultiplicationTable (std::streambuf* buffer, int num) { std::ostream hexout(buffer); hexout << std::hex << std::showbase; for (int i=1; i<=num; ++i) { for (int j=1; j<=10; ++j) { hexout << i*j << ' '; } hexout << std::endl; } } // does NOT close buffer int main() { using namespace std; int num = 5; cout << "We print " << num << " lines hexadecimal" << endl; hexMultiplicationTable(cout.rdbuf(),num); cout << "That was the output of " << num << " hexadecimal lines " << endl; return EXIT_SUCCESS; } // We print 5 lines hexadecimal // 0x1 0x2 0x3 0x4 0x5 0x6 0x7 0x8 0x9 0xa // 0x2 0x4 0x6 0x8 0xa 0xc 0xe 0x10 0x12 0x14 // 0x3 0x6 0x9 0xc 0xf 0x12 0x15 0x18 0x1b 0x1e // 0x4 0x8 0xc 0x10 0x14 0x18 0x1c 0x20 0x24 0x28 // 0x5 0xa 0xf 0x14 0x19 0x1e 0x23 0x28 0x2d 0x32 // That was the output of 5 hexadecimal lines ////////// io/redirect.cpp p641 #include #include using namespace std; void redirect(ostream&); int main() { cout << "the first row" << endl; redirect(cout); cout << "the last row" << endl; return EXIT_SUCCESS; } void redirect (ostream& strm) { ofstream file("redirect.txt"); // save output buffer of the stream streambuf* strm_buffer = strm.rdbuf(); // redirect ouput into the file strm.rdbuf (file.rdbuf()); file << "one row for the file" << endl; strm << "one row for the stream" << endl; // restore old output buffer strm.rdbuf (strm_buffer); } // closes file AND its buffer automatically // the first row // the last row // // D:\projects\AdvCpp> type redirect.txt // one row for the file // one row for the stream ////////// io/rw1.cpp p643 #include #include using namespace std; int main() { // open file ``example.dat'' for reading and writing filebuf buffer; ostream output(&buffer); istream input(&buffer); buffer.open ("example.dat", ios::in | ios::out | ios::trunc); for (int i=1; i<=4; i++) { // write one line output << i << ". line" << endl; // print all file contents input.seekg(0); // seek to the beginning char c; while (input.get(c)) { cout.put(c); } cout << endl; input.clear(); // clear eofbit and failbit } return EXIT_SUCCESS; } // 1. line // // 1. line // 2. line // // 1. line // 2. line // 3. line // // 1. line // 2. line // 3. line // 4. line ////////// io/sstr1.cpp p647 #include #include #include using namespace std; int main() { ostringstream os; // decimal and hexadecimal value os << "dec: " << 15 << hex << " hex: " << 15 << endl; cout << os.str() << endl; // append floating value and bitset bitset<15> b(5789); os << "float: " << 4.67 << " bitset: " << b << endl; // overwrite with octal value os.seekp(0); os << "oct: " << oct << 15; cout << os.str() << endl; return EXIT_SUCCESS; } // dec: 15 hex: f // // oct: 17 hex: f // float: 4.67 bitset: 001011010011101 ////////// io/frac2out.hpp p653 #include #include template inline std::basic_ostream& operator << (std::basic_ostream& strm, const Fraction& f) { /* string stream * - with same format * - without special field width */ std::basic_ostringstream s; s.copyfmt(strm); s.width(0); // fill string stream s << f.numerator() << '/' << f.denominator(); // print string stream strm << s.str(); return strm; } ////////// io/frac2in.hpp p655 #include template inline std::basic_istream& operator >> (std::basic_istream& strm, Fraction& f) { int n, d; // read value of numerator strm >> n; /* if available * - read '/' and value of demonimator */ if (strm.peek() == '/') { strm.ignore(); strm >> d; } else { d = 1; } /* if denominator is zero * - set failbit as I/O format error */ if (d == 0) { strm.setstate(std::ios::failbit); return strm; } /* if everything is fine so far * change the value of the fraction */ if (strm) { f = Fraction(n,d); } return strm; } ////////// io/charcat2.cpp p667 #include #include using namespace std; int main() { // input stream buffer iterator for cin istreambuf_iterator inpos(cin); // end-of-stream iterator istreambuf_iterator endpos; // output stream buffer iterator for cout ostreambuf_iterator outpos(cout); // while input iterator is valid while (inpos != endpos) { *outpos = *inpos; // assign its value to the output iterator ++inpos; ++outpos; } return EXIT_SUCCESS; } // now is the time // now is the time // for all good men // for all good men // ^Z ////////// io/countlines.cpp p667 ?? #include #include #include #include int countLines (std::istream& in); int main (int argc, char* argv[]) { int count; if (argc == 1) { // no argument => count lines of standard input count = countLines(std::cin); } else { // count number of lines of all files passed as argument std::ifstream in; count = 0; for (int i=1; i(in), std::istreambuf_iterator(), '\n'); } // D:\projects\AdvCpp\Debug> advcpp one.txt two.txt // 6 ////////// io/outbuf1.cpp p670 #include /********* #include "outbuf1x.hpp" *********/ #include #include #include using std::char_traits; template > class basic_outbuf : public std::basic_streambuf { protected: /* central output function * - print characters in uppercase mode */ virtual int_type overflow (int_type c) { if (!traits::eq_int_type(c,traits::eof())) { // convert lowercase to uppercase c = std::toupper(c,getloc()); // and write the character to the standard output if (putchar(c) == EOF) { return traits::eof(); } } return traits::not_eof(c); } }; typedef basic_outbuf outbuf; typedef basic_outbuf woutbuf; /********* #include "outbuf1x.hpp" *********/ int main() { outbuf ob; // create special output buffer std::ostream out(&ob); // initialize output stream with that output buffer out << "31 hexadecimal: " << std::hex << 31 << std::endl; return EXIT_SUCCESS; } // 31 HEXADECIMAL: 1F ////////// io/outbuf2.cpp p672 #include /********* #include "outbuf2.hpp" *********/ #include #include #include extern "C" { int write (int fd, const char* buf, int num); } class fdoutbuf : public std::streambuf { protected: int fd; // file descriptor public: // constructor fdoutbuf (int _fd) : fd(_fd) { } protected: // write one character virtual int_type overflow (int_type c) { if (c != EOF) { char z = c; if (write (fd, &z, 1) != 1) { return EOF; } } return c; } // write multiple characters virtual std::streamsize xsputn (const char* s, std::streamsize num) { return write(fd,s,num); } }; using std::ostream; class fdostream : public ostream { protected: fdoutbuf buf; public: fdostream (int fd) : ostream(&buf), buf(fd) { } }; /********* #include "outbuf2.hpp" *********/ int main() { fdostream out(1); // stream with buffer writing to file descriptor 1 out << "31 hexadecimal: " << std::hex << 31 << std::endl; return EXIT_SUCCESS; } // 31 hexadecimal: 1f ////////// io/outbuf3.cpp p673 #include /********* #include "outbuf3.hpp" *********/ #include #include extern "C" { int write (int fd, const char* buf, int num); } class outbuf : public std::streambuf { protected: enum { bufferSize = 10 }; // size of data buffer char buffer[bufferSize]; // data buffer public: /* constructor * - initialize data buffer * - one character less to let the bufferSizeth character * cause a call of overflow() */ outbuf() { setp (buffer, buffer+(bufferSize-1)); } /* destructor * - flush data buffer */ virtual ~outbuf() { sync(); } protected: // flush the characters in the buffer int flushBuffer () { int num = pptr()-pbase(); if (write (1, buffer, num) != num) { return EOF; } pbump (-num); // reset put pointer accordingly return num; } /* buffer full * - write c and all previous characters */ virtual int_type overflow (int_type c) { if (c != EOF) { // insert character into the buffer *pptr() = c; pbump(1); } // flush the buffer if (flushBuffer() == EOF) { // ERROR return EOF; } return c; } /* synchronize data with file/destination * - flush the data in the buffer */ virtual int sync () { if (flushBuffer() == EOF) { // ERROR return -1; } return 0; } }; /********* #include "outbuf3.hpp" *********/ int main() { outbuf ob; // create special output buffer std::ostream out(&ob); // initialize output stream with that output buffer out << "31 hexadecimal: " << std::hex << 31 << std::endl; return EXIT_SUCCESS; } // 31 hexadecimal: 1f ////////// io/inbuf1.cpp p678 #include /********* #include "inbuf1.hpp" *********/ #include #include #include extern "C" { int read (int fd, char* buf, int num); } class inbuf : public std::streambuf { protected: /* data buffer: * - at most, four characters in putback area plus * - at most, six characters in ordinary read buffer */ enum { 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 *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) */ memcpy (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 *gptr(); } }; /********* #include "inbuf1.hpp" *********/ 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; return EXIT_SUCCESS; } // 1234567890 // 123456787890 // 1234567890 // 1234567 ////////// io/copy1.cpp p683 #include int main () { // copy all standard input to standard output std::cout << std::cin.rdbuf(); return 0; } // the quick brown fox // the quick brown fox // jumped over the lazy dog // jumped over the lazy dog // ^Z ////////// io/copy2.cpp p684 #include int main () { // copy all standard input to standard output std::cin >> std::noskipws >> std::cout.rdbuf(); return 0; } // the quick brown fox // the quick brown fox // jumped over the lazy dog // jumped over the lazy dog // ^Z #endif