string标准库的重载>>是如何实现的(当输入的数据量很大时)
string标准库的重载>>是怎么实现的(当输入的数据量很大时)?
我这种显然不行,求高人指点
------解决方案--------------------
不是很明白你的意思,你是要把所有的输入搞成一个字符串吗?
你的代码可以简化如下:
我这种显然不行,求高人指点
- C/C++ code
std::istream& operator>>(std::istream &in,string &str) { char temp[80]; in>>temp; str = string(temp); return in; }
------解决方案--------------------
不是很明白你的意思,你是要把所有的输入搞成一个字符串吗?
你的代码可以简化如下:
- C/C++ code
std::istream& operator>>(std::istream &in,string &str) { in>>str; return in; }
------解决方案--------------------
建议楼主去看stl中string的源代码。
------解决方案--------------------
- C/C++ code
template<class _FwdIterator> static _CharT* _S_construct(_FwdIterator __beg, _FwdIterator __end, const _Alloc& __a, forward_iterator_tag) { if (__beg == __end && __a == _Alloc()) return _S_empty_rep()._M_refdata(); // NB: Not required, but considered best practice. if (__builtin_expect(__is_null_pointer(__beg), 0)) __throw_logic_error(__N("basic_string::_S_construct NULL not valid")); const size_type __dnew = static_cast<size_type>(std::distance(__beg,__end)); // Check for out_of_range and length_error exceptions. //直接根据已知数据长度分配字符串的空间 _Rep* __r = _Rep::_S_create(__dnew, size_type(0), __a); try { _S_copy_chars(__r->_M_refdata(), __beg, __end); } catch(...) { __r->_M_destroy(__a); __throw_exception_again; } __r->_M_length = __dnew; __r->_M_refdata()[__dnew] = _Rep::_S_terminal; // grrr. return __r->_M_refdata(); }
------解决方案--------------------
string是basic_string模板的特化,头文件中有他的重载实现
- C/C++ code
template<class _Elem, class _Traits, class _Alloc> inline basic_istream<_Elem, _Traits>& operator>>( basic_istream<_Elem, _Traits> && _Istr, basic_string<_Elem, _Traits, _Alloc>& _Str) { // extract a string typedef ctype<_Elem> _Ctype; typedef basic_istream<_Elem, _Traits> _Myis; typedef basic_string<_Elem, _Traits, _Alloc> _Mystr; typedef typename _Mystr::size_type _Mysizt; ios_base::iostate _State = ios_base::goodbit; bool _Changed = false; const typename _Myis::sentry _Ok(_Istr); if (_Ok) { // state okay, extract characters const _Ctype& _Ctype_fac = _USE(_Istr.getloc(), _Ctype); _Str.erase(); _TRY_IO_BEGIN _Mysizt _Size = 0 < _Istr.width() && (_Mysizt)_Istr.width() < _Str.max_size() ? (_Mysizt)_Istr.width() : _Str.max_size(); typename _Traits::int_type _Meta = _Istr.rdbuf()->sgetc(); for (; 0 < _Size; --_Size, _Meta = _Istr.rdbuf()->snextc()) if(_Traits::eq_int_type(_Traits::eof(), _Meta)) { // end of file, quit _State |= ios_base::eofbit; break; } else if (_Ctype_fac.is(_Ctype::space, _Traits::to_char_type(_Meta))) break; // whitespace, quit else { // add character to string _Str.append(1, _Traits::to_char_type(_Meta)); _Changed = true; } _CATCH_IO_(_Istr) } _Istr.width(0); if (!_Changed) _State |= ios_base::failbit; _Istr.setstate(_State); return (_Istr); }