cin.getline对cin.gcount()的影响 - delphiwcdj的专栏 - 博客频道 - CSDN.NET
2011-05-08 wcdj
问题 :
测试下面代码,解释cin.gcount的输出为什么会不同?
- #include<iostream>
- using namespace std;
- int main()
- {
- // case 1:
- char a[10];
- cin.getline(a,10); // 123456789
- cout << a << endl; // 123456789
- cout << cin.gcount(); // Note, 10
- cout << endl;
- // case 2:
- char b[10];
- cin.getline(b,10); // 1234567890
- cout << b << endl; // 123456789
- cout << cin.gcount(); // Note, 9
- return 0;
- }
分析 :
getline()是按行读入字符串,后面可以指定2个参数或3个参数,其在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()函数。
同时当我们单步进入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 (_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; // 遇到文件尾,getline结束
- break ;
- }
- 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 ;
- } // 读到了指定个数,执行到这里已经隐含了在指定个数的最后一位仍然不是结束符,由于在执行这部分时,在对长度计数器没有进行++操作
- else
- { // got a character, add it to string
- ++_Chcount;
- *_Str++ = _Traits::to_char_type(_Meta);
- }
- _CATCH_IO_END
- }
- *_Str = _Elem(); // add terminating null character
- _Myios::setstate(_Chcount == 0 ? _State | ios_base::failbit : _State);
- return (* this );
- }
所以在对于输入 12345789 时,在最后我们输入了 '/n',因此在判断时,计数器仍然加1,而相对当我们输入 1234567890 时,在判断 a[9] 时,由于--_Count <= 0,所以计数器没有被递加,因此在产生了区别。
结论:
通过对getline的分析,可以找到输出结果不同的原因。
PS:
MSDN:
basic_istream::gcount
Returns the number of characters read during the last unformatted input.
- streamsize gcount( ) const ;
Return Value
The extraction count.
Remarks
Use basic_istream::get to read unformatted characters.
Example
- // basic_istream_gcount.cpp
- // compile with: /EHsc
- #include <iostream>
- using namespace std;
- int main( )
- {
- cout << "Type the letter 'a': " ;
- ws( cin );
- char c[10];
- cin.get( &c[0],9 ); // a
- cout << c << endl; // a
- cout << cin.gcount( ) << endl; // 1 注意,这里为什么是1,分析方法同getline,可以在get的实现中找的具体的原因
- }
Requirements
Header: <istream>
Namespace: std
参考 :istream::getline
http://www.cplusplus.com/reference/iostream/istream/getline/
istream::get
http://www.cplusplus.com/reference/iostream/istream/get/
basic_istream::gcount
http://www.cplusplus.com/reference/iostream/istream/gcount/
http://msdn.microsoft.com/zh-cn/library/3w9exa29%28v=VS.90%29.aspx
cin.getline()
http://blog.csdn.net/kof2001kop/archive/2011/04/03/6299778.aspx
http://social.msdn.microsoft.com/Forums/zh-CN/visualcpluszhchs/thread/bacc495d-1170-4a20-90b6-80a37ba3d5b5