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 newline return (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 extract int_type _Metadelim = _Traits::to_int_type(_Delim); _TRY_IO_BEGIN int_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的执行过程的,还是很有意思的~~