getline 细节

来源:互联网 发布:维氏硬度计软件 编辑:程序博客网 时间:2024/06/07 06:09

from: http://zhidao.baidu.com/link?url=J1er202u3NAx1A_wlx1Tym4Px-nCPqQq37D7w2v-uYFztCexSf7_JPsS7FvXnNaSFk9SHyVQ9sJlmGCM1971i_


getline后面可以指定2个参数或3个参数,2个参数时,第2个参数就是读取的位数,3个参数时,第3个参数是终止符,只要2个参数中有一个满足了,就停止读入,如楼上方式,将会是读5个字符或者遇到'\n'停止—————————————————哎,今天用到getline,仔细研究一番才发现楼主这问题问的这么深刻,来看一下getline的实现吧,共同学习之~~以下为getline函数的实现,在头文件istream中。下面具体分析一下,太深奥的分析不了,只简述一下,已经足够用了:_Myt& __CLR_OR_THIS_CALL getline(_Elem *_Str, streamsize _Count){// get up to _Count characters into NTCS, discard newlinereturn (getline(_Str, _Count, _Myios::widen('\n')));}//注:可以看出,两个参数的getline实际也是调用了以'\n'为结束符的三参数getline函数。_Myt& __CLR_OR_THIS_CALL getline(_Elem *_Str,streamsize _Count, _Elem _Delim){// get up to _Count characters into NTCS, discard _Delim_DEBUG_POINTER(_Str);ios_base::iostate _State = ios_base::goodbit;_Chcount = 0;const sentry _Ok(*this, true);//注:这句关键,它关系到下面的if是否执行,也就是是否读输入流,整个函数流程太多了,也没看十分明白,但可以肯定的是,当输入流的状态是正常时,该函数的返回值也是true,反之,则返回false。if (_Ok && 0 < _Count){// state okay, use facet to extractint_type _Metadelim = _Traits::to_int_type(_Delim);_TRY_IO_BEGINint_type _Meta = _Myios::rdbuf()->sgetc();//注:从输入流读一个字符for (; ; _Meta = _Myios::rdbuf()->snextc())if (_Traits::eq_int_type(_Traits::eof(), _Meta)){// end of file, quit_State |= ios_base::eofbit;break;}//注:遇到文件尾,getline结束else if (_Meta == _Metadelim){// got a delimiter, discard it and quit++_Chcount;_Myios::rdbuf()->sbumpc();//注:这句把结束符读掉了,如果不指定结束符,那就是把'\n'读掉了。break;}//注:遇到结束符,getline结束,注意这里的顺序,它是先判断是否遇到结束符,后判断是否读入了指定个数的。else if (--_Count <= 0){// buffer full, quit_State |= ios_base::failbit;break;}//注:读到了指定个数,执行到这里已经隐含了在指定个数的最后一位仍然不是结束符,因此该部分将输入流状态置为了错误。这直接导致了接下来的getline(或者get/>>等等都是不能正确执行的)else{// got a character, add it to string++_Chcount;*_Str++ = _Traits::to_char_type(_Meta);}//注:正常读取一个字符_CATCH_IO_END}*_Str = _Elem();// add terminating null character//注:前面这句为字符串加入了终止符'\0'_Myios::setstate(_Chcount == 0 ? _State | ios_base::failbit : _State);//注:如果没有读入任何字符,要保持执行这一次getline之前的输入流状态,否则根据这一次getline执行的情况,设置输入流为相应状态。return (*this);}分析完这些就很容易理解楼主所说的情况了:(1)输入abcd"回车",getline(s,5)遇到换行符结束,输入流状态仍然正确。(2)输入abcd"空格""回车",getline(s,5)在第5位遇到了空格,因已读满字符串而结束,输入流状态变为了错误,此后的getline(s2,4)是无法读输入流的。但如果在执行getline(s,5)后加一句cin.clear();将输入流状态重新设置为正常,之后再执行getline(s2,4)你就会发现此时是可以继续从输入流读数据的了。至于你说换行符被s2接收?那是因为你输出完s之后又endl的现象吧,看结果是换了一行,实际s2里是什么都没有。楼主有兴趣的话可以单步跟踪调试去看一下getline的执行过程的,还是很有意思的~~

0 0
原创粉丝点击