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); }