C++ stream extraction operator overloading -


this question philosophy (canonical design) of user-written c++ input stream extraction operators (>>).

assume on entry >> operator implementation (for user-written class), eof flag set input stream.

should user-written extraction operator (>>)

  1. set failure flag (because no instance of desired object can found)
  2. should return caller eof flag still set.

if second approach used, implies caller must check eof flag before attempt made invoke >> operator. reason >> operator might extract instance of desired class , set eof flag.

the original code follows. based on comments below, code appears wrong. if eof set on input, extraction operator return eof still set. appears if eof set, bad , fail not set, extraction of string should done set fail bit. of course, fail bit can set directly.

/* implement c/c++ >> (stream input) operator non-member     function */ std::istream &operator>>(std::istream& is, decnumber &val) {   deccontext  context{deccontext::definit};   uint32_t    status;   /* true value below prevents whitespace being skipped */   std::istream::sentry  s(is, true);   std::string           instr;   /* check if input stream in state. return      caller if input stremm not in state. caller      must handle condition. */   if(!s)      return is;    /* string input stream. string converted       decnumber below. return caller if step causes      stream related errors. note reaching end of       input not stream related error here. decimal number might      absolute last thing in stream. */   >> instr;   if (is.bad() || is.fail())     return is;   /* try convert string decnumber using default context      value */   decnumberfromstring(val.getdecval(), instr.c_str(), context.getdeccont());   status = context.deccontextgetstatus();   /* remove few status bits don't care */   status &= ~(dec_inexact + dec_rounded);   if (status)     is.setstate(std::ios_base::failbit);    return is; } 

you should implement solution 1.

when in doubt, @ what's being done. can see below, fail bit being set if try read stream in eof state.

note eof not way fail though. try setting std::string vals = "52 43 a"; in code below.

failbit should set if for reason, operator>> doesn't stream value. eof 1 of reasons.

#include <sstream> #include <iostream> #include <string>  void print_stream (std::istream & print_me, int const & i) {   std::cout << "i: " << << "\n";   std::ios_base::iostate bits = print_me.rdstate();    std::cout << "good: " << (bits & std::ios_base::goodbit) <<      ", bad: " << (bits & std::ios_base::badbit) <<      ", fail: " << (bits & std::ios_base::failbit) <<     ", eof: " << (bits & std::ios_base::eofbit) << "\n";    std::cout << "\n----------------------------\n\n"; }  int main (void) {   std::string vals = "52 43";   std::istringstream iss(vals);   int i;    iss >> i;   print_stream (iss, i);   iss >> i;   print_stream (iss, i);   iss >> i;   print_stream (iss, i);   iss >> i;   print_stream (iss, i);    return 0; } 

outputs

$ ./a.exe i: 52 good: 0, bad: 0, fail: 0, eof: 0  ----------------------------  i: 43 good: 0, bad: 0, fail: 0, eof: 2  ----------------------------  i: 43 good: 0, bad: 0, fail: 4, eof: 2  ----------------------------  i: 43 good: 0, bad: 0, fail: 4, eof: 2  ---------------------------- 

note typical read pattern loop variation of...

while (input >> var >> var2 >> var3) {   // failbit not set.  reads succeeded.   // stuff } 

if need detect whether fail happened @ point during reading of multiple values yea, need little more sophisticated , testing like...

while (true) {   if (input >> var)   {     // read first value     if (input >> var2 >> var3)     {       // succesfully read values!       // stuff     }     else     {       errorlog ("partial line read!");       break;     }   else   {     // nothing else read     break;   } } 

Comments

Popular posts from this blog

javascript - Bootstrap Popover: iOS Safari strange behaviour -

Magento/PHP - Get phones on all members in a customer group -

session - Logging Out Using PHP -