///////////////////////////////////////////// // MT4Q4.cpp - implementing pushbacks #include #include #include //////////////////////////////////////////////////////////// // std::istream only guarantees that a single putback char // will work, provided that the user extracts one or more chars // before the next putback, e.g., there may only be storage in // the stream for a single putback character. // // Ideal solutions for this problem would be to override // virtual functions sbumpc and getc in a class derived from // streambuf, as those functions are used to supply chars // to istream. Unfortunately that plot is foiled because // std::streambuf does not make them virtual - sigh! // // Overriding get(), getc(), and all the other variants in // std::istream is also foiled as they are not virtual. // That only leaves us with the option of tacking on an // extended interface to accomplish multiple putbacks, as // illustrated below. // namespace CSE687 { class istreamWithPushback : public std::istream { public: istreamWithPushback(std::streambuf* pSb) : std::istream(pSb) {} void pushback(int ch); int getback(); private: std::queue backChars; }; void istreamWithPushback::pushback(int ch) { backChars.push(ch); } int istreamWithPushback::getback() { int ch; if(backChars.size() > 0) { ch = backChars.front(); backChars.pop(); return ch; } return std::istream::get(); } } using namespace::CSE687; void main() { char ch, ch1, ch2; std::istringstream ss("abcdefghijklmnopqrstuvwxyz"); istreamWithPushback iwpb(ss.rdbuf()); std::cout << "\n the input stream contains:"; std::cout << "\n " << ss.rdbuf(); ss.seekg(0); iwpb >> ch; std::cout << "\n read: " << ch; iwpb >> ch; std::cout << "\n read: " << ch; iwpb >> ch1; std::cout << "\n read: " << ch1; iwpb >> ch2; std::cout << "\n read: " << ch2; std::cout << "\n pushing back " << ch1 << ":"; iwpb.pushback(ch1); std::cout << "\n pushing back " << ch2 << ":"; iwpb.pushback(ch2); std::cout << "\n the input stream now contains:"; std::cout << "\n "; while(iwpb.good()) { ch = iwpb.getback(); std::cout << ch; } std::cout << "\n\n"; }