_istream.c

来自「stl的源码」· C语言 代码 · 共 1,430 行 · 第 1/4 页

C
1,430
字号
_STLP_MOVE_TO_STD_NAMESPACEtemplate <class _CharT, class _Traits>basic_istream<_CharT, _Traits>&basic_istream<_CharT, _Traits>::get(_CharT* __s, streamsize __n,                                    _CharT __delim) {  sentry __sentry(*this, _No_Skip_WS());  this->_M_gcount = 0;  if (__sentry) {    if (__n > 0) {      basic_streambuf<_CharT, _Traits>* __buf = this->rdbuf();      if (__buf->egptr() != __buf->gptr())        this->_M_gcount =          _STLP_PRIV __read_buffered(this,  __buf, __n - 1, __s,                                     _STLP_PRIV _Eq_char_bound<_Traits>(__delim),                                     _STLP_PRIV _Scan_for_char_val<_Traits>(__delim),                                     false, true, false);      else        this->_M_gcount =          _STLP_PRIV __read_unbuffered(this,  __buf, __n - 1, __s,                                       _STLP_PRIV _Eq_char_bound<_Traits>(__delim),                                       false, true, false);    }  }  if (this->_M_gcount == 0)    this->setstate(ios_base::failbit);  return *this;}// Getline is essentially identical to get, except that it extracts// the delimiter.template <class _CharT, class _Traits>basic_istream<_CharT, _Traits>&basic_istream<_CharT, _Traits>::getline(_CharT* __s, streamsize __n,                                        _CharT __delim) {  sentry __sentry(*this, _No_Skip_WS());  this->_M_gcount = 0;  if (__sentry) {    if (__n > 0) {      basic_streambuf<_CharT, _Traits>* __buf = this->rdbuf();      this->_M_gcount = __buf->egptr() != __buf->gptr()        ? _STLP_PRIV __read_buffered(this,  __buf, __n - 1, __s,                                     _STLP_PRIV _Eq_char_bound<_Traits>(__delim),                                     _STLP_PRIV _Scan_for_char_val<_Traits>(__delim),                                     true, true, true)        : _STLP_PRIV __read_unbuffered(this,  __buf, __n - 1, __s,                                       _STLP_PRIV _Eq_char_bound<_Traits>(__delim),                                       true, true, true);    }  }  if (this->_M_gcount == 0)    this->setstate(ios_base::failbit);  return *this;}// Read n characters.  We don't look for any delimiter, and we don't// put in a terminating null character.template <class _CharT, class _Traits>basic_istream<_CharT, _Traits>&basic_istream<_CharT, _Traits>::read(char_type* __s, streamsize __n) {  sentry __sentry(*this, _No_Skip_WS());  this->_M_gcount = 0;  if (__sentry && !this->eof()) {    basic_streambuf<_CharT, _Traits>*__buf = this->rdbuf();    if (__buf->gptr() != __buf->egptr())      _M_gcount        = _STLP_PRIV __read_buffered(this,  __buf, __n, __s,                                     _STLP_PRIV _Constant_unary_fun<bool, int_type>(false),                                     _STLP_PRIV _Project2nd<const _CharT*, const _CharT*>(),                                     false, false, false);    else      _M_gcount        = _STLP_PRIV __read_unbuffered(this,  __buf, __n, __s,                                       _STLP_PRIV _Constant_unary_fun<bool, int_type>(false),                                       false, false, false);  }  else    this->setstate(ios_base::failbit);  if (this->eof())    this->setstate(ios_base::eofbit | ios_base::failbit);  return *this;}// Read n or fewer characters.  We don't look for any delimiter, and// we don't put in a terminating null character.template <class _CharT, class _Traits>streamsizebasic_istream<_CharT, _Traits>::readsome(char_type* __s, streamsize __nmax) {  sentry __sentry(*this, _No_Skip_WS());  this->_M_gcount = 0;  if (__sentry && !this->eof() && __nmax >= 0) {    basic_streambuf<_CharT, _Traits>* __buf = this->rdbuf();    streamsize __avail = __buf->in_avail();    // fbp : isn't full-blown setstate required here ?    if (__avail == -1)      this->_M_setstate_nothrow(ios_base::eofbit);    else if (__avail != 0) {      if (__buf->gptr() != __buf->egptr())        _M_gcount          = _STLP_PRIV __read_buffered(this,  __buf, (min) (__avail, __nmax), __s,                                       _STLP_PRIV _Constant_unary_fun<bool, int_type>(false),                                       _STLP_PRIV _Project2nd<const _CharT*, const _CharT*>(),                                       false, false, false);      else        _M_gcount          = _STLP_PRIV __read_unbuffered(this,  __buf, (min) (__avail, __nmax), __s,                                         _STLP_PRIV _Constant_unary_fun<bool, int_type>(false),                                         false, false, false);    }  }  else {    // fbp : changed so that failbit is set only there, to pass Dietmar's test    if (this->eof())      this->setstate(ios_base::eofbit | ios_base::failbit);    else      this->setstate(ios_base::failbit);  }  //  if (this->eof())  //    this->setstate(ios_base::eofbit | ios_base::failbit);  return _M_gcount;}template <class _CharT, class _Traits>void basic_istream<_CharT, _Traits>::_M_formatted_get(_CharT* __s) {  sentry __sentry(*this); // Skip whitespace.  if (__sentry) {    basic_streambuf<_CharT, _Traits>* __buf = this->rdbuf();    streamsize __nmax = this->width() > 0      ? this->width() - 1      : ((numeric_limits<streamsize>::max)() / sizeof(_CharT)) - 1;    streamsize __n = __buf->gptr() != __buf->egptr()      ? _STLP_PRIV __read_buffered(this,  __buf, __nmax, __s,                                   _STLP_PRIV _Is_wspace_null<_Traits>(this->_M_ctype_facet()),                                   _STLP_PRIV _Scan_wspace_null<_Traits>(this->_M_ctype_facet()),                                   false, true, false)      : _STLP_PRIV __read_unbuffered(this,  __buf, __nmax, __s,                                     _STLP_PRIV _Is_wspace_null<_Traits>(this->_M_ctype_facet()),                                     false, true, false);    if (__n == 0)      this->setstate(ios_base::failbit);  }  this->width(0);}// A generic unbuffered function for ignoring characters.  We stop// when we reach EOF, or when the function object __is_delim returns// true.  In the last case, it extracts the character for which// __is_delim is true, if and only if __extract_delim is true.template < class _CharT, class _Traits, class _Is_Delim>void _STLP_CALL_M_ignore_unbuffered(basic_istream<_CharT, _Traits>* __that,                     basic_streambuf<_CharT, _Traits>* __buf,                     _Is_Delim __is_delim,                     bool __extract_delim, bool __set_failbit) {  bool __done = false;  ios_base::iostate __status = 0;  typedef typename basic_istream<_CharT, _Traits>::int_type int_type;  _STLP_TRY {    while (!__done) {      int_type __c = __buf->sbumpc();      if (__that->_S_eof(__c)) {        __done = true;        __status |= __set_failbit ? ios_base::eofbit | ios_base::failbit                                  : ios_base::eofbit;      }      else if (__is_delim(_Traits::to_char_type(__c))) {        __done = true;        if (!__extract_delim)          if (__that->_S_eof(__buf->sputbackc(_Traits::to_char_type(__c))))            __status |= ios_base::failbit;      }    }  }  _STLP_CATCH_ALL {    __that->_M_handle_exception(ios_base::badbit);  }  __that->setstate(__status);}// A generic buffered function for ignoring characters.  Much like// _M_ignore_unbuffered, but with one additional function object:// __scan_delim(first, last) returns the first pointer p in [first,// last) such that __is_delim(p) is true.template < class _CharT, class _Traits, class _Is_Delim, class _Scan_Delim>void _STLP_CALL_M_ignore_buffered(basic_istream<_CharT, _Traits>* __that,                   basic_streambuf<_CharT, _Traits>* __buf,                   _Is_Delim __is_delim, _Scan_Delim __scan_delim,                   bool __extract_delim, bool __set_failbit) {  bool __at_eof      = false;  bool __found_delim = false;  _STLP_TRY {    while (__buf->_M_egptr() != __buf->_M_gptr() && !__at_eof && !__found_delim) {      const _CharT* __p = __scan_delim(__buf->_M_gptr(), __buf->_M_egptr());      __buf->_M_gbump((int)(__p - __buf->_M_gptr()));      if (__p != __buf->_M_egptr()) { // We found delim, so we're done.        if (__extract_delim)          __buf->_M_gbump(1);        __found_delim = true;      }      else                         // No delim.  Try to refil the buffer.        __at_eof = __that->_S_eof(__buf->sgetc());    }                              // Close the while loop.  }  _STLP_CATCH_ALL {    __that->_M_handle_exception(ios_base::badbit);    return;  }  if (__at_eof) {    __that->setstate(__set_failbit ? ios_base::eofbit | ios_base::failbit                                   : ios_base::eofbit);    return;  }  if (__found_delim)    return;  // If execution has reached this point, then we have an empty buffer but  // we have not reached eof.  What that means is that the streambuf has  // decided to switch from a buffered to an unbuffered mode.  We switch  // to _M_ignore_unbuffered.  _M_ignore_unbuffered(__that,  __buf, __is_delim, __extract_delim, __set_failbit);}// Overloaded versions of _M_ignore_unbuffered and _M_ignore_unbuffered// with an explicit count _Num.  Return value is the number of// characters extracted.//// The function object __max_chars takes two arguments, _Num and __n// (the latter being the number of characters we have already read),// and returns the maximum number of characters to read from the buffer.// We parameterize _M_ignore_buffered so that we can use it for both// bounded and unbounded input; for the former the function object should// be minus<>, and for the latter it should return a constant maximum value.template < class _CharT, class _Traits, class _Max_Chars, class _Is_Delim>streamsize _STLP_CALL_M_ignore_unbuffered(basic_istream<_CharT, _Traits>* __that,                     basic_streambuf<_CharT, _Traits>* __buf,                     streamsize _Num, _Max_Chars __max_chars,                     _Is_Delim __is_delim,                     bool __extract_delim, bool __set_failbit) {  streamsize __n = 0;  ios_base::iostate __status = 0;  typedef typename basic_istream<_CharT, _Traits>::int_type int_type;  _STLP_TRY {    while (__max_chars(_Num, __n) > 0) {      int_type __c = __buf->sbumpc();      if (__that->_S_eof(__c)) {        __status |= __set_failbit ? ios_base::eofbit | ios_base::failbit                                  : ios_base::eofbit;        break;      }      else if (__is_delim(_Traits::to_char_type(__c))) {        if (__extract_delim)          ++__n;        else if (__that->_S_eof(__buf->sputbackc(_Traits::to_char_type(__c))))          __status |= ios_base::failbit;        break;      }      // fbp : added counter increment to pass Dietmar's test      ++__n;    }  }  _STLP_CATCH_ALL {    __that->_M_handle_exception(ios_base::badbit);  }  if (__status)    __that->setstate(__status);   // This might throw.  return __n;}template < class _CharT, class _Traits, class _Max_Chars, class _Is_Delim, class _Scan_Delim>streamsize _STLP_CALL_M_ignore_buffered(basic_istream<_CharT, _Traits>* __that,                   basic_streambuf<_CharT, _Traits>* __buf,                   streamsize _Num,                   _Max_Chars __max_chars,                   _Is_Delim __is_delim, _Scan_Delim __scan_delim,                   bool __extract_delim, bool __set_failbit) {  streamsize __n = 0;  bool __at_eof = false;  bool __done   = false;  _STLP_TRY {    while (__buf->_M_egptr() != __buf->_M_gptr() && !__done) {      ptrdiff_t __avail = __buf->_M_egptr() - __buf->_M_gptr();      streamsize __m = __max_chars(_Num, __n);      if (__avail >= __m) {       // We have more characters than we need.        const _CharT* __last = __buf->_M_gptr() + __STATIC_CAST(ptrdiff_t, __m);        const _CharT* __p = __scan_delim(__buf->_M_gptr(), __last);        ptrdiff_t __chunk = __p - __buf->_M_gptr();        __n += __chunk;        __buf->_M_gbump((int)__chunk);        if (__extract_delim && __p != __last) {          __n += 1;          __buf->_M_gbump(1);        }        __done = true;      }      else {        const _CharT* __p = __scan_delim(__buf->_M_gptr(), __buf->_M_egptr());        ptrdiff_t __chunk = __p - __buf->_M_gptr();        __n += __chunk;        __buf->_M_gbump((int)__chunk);        if (__p != __buf->_M_egptr()) { // We found delim.          if (__extract_delim) {            __n += 1;            __buf->_M_gbump(1);          }          __done = true;        }        // We didn't find delim.  Try to refill the buffer.        else if (__that->_S_eof(__buf->sgetc())) {          __done   = true;          __at_eof = true;        }

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?