zoukankan      html  css  js  c++  java
  • cin.getline对cin.gcount()的影响

    cin.getline对cin.gcount()的影响 - delphiwcdj的专栏 - 博客频道 - CSDN.NET

    cin.getline对cin.gcount()的影响

    分类: C/C++ 195人阅读 评论(0) 收藏 举报

    2011-05-08 wcdj

    问题

    测试下面代码,解释cin.gcount的输出为什么会不同?

    1. #include<iostream>  
    2. using namespace std;  
    3. int main()  
    4. {  
    5.     // case 1:  
    6.     char a[10];  
    7.     cin.getline(a,10);              // 123456789  
    8.     cout << a << endl;          // 123456789  
    9.     cout << cin.gcount();     // Note, 10  
    10.     cout << endl;  
    11.     // case 2:  
    12.     char b[10];  
    13.     cin.getline(b,10);              // 1234567890  
    14.     cout << b << endl;          // 123456789  
    15.     cout << cin.gcount();     // Note, 9  
    16.     return 0;  
    17. }  

    分析

    getline()是按行读入字符串,后面可以指定2个参数或3个参数,其在istream中的实现如下:

    [cpp:nogutter] view plaincopyprint?
    1. _Myt& __CLR_OR_THIS_CALL getline(_Elem *_Str, streamsize _Count)  
    2. {   // get up to _Count characters into NTCS, discard newline  
    3.     return (getline(_Str, _Count, _Myios::widen('/n')));  
    4. }  

    可以看出,两个参数的getline()实际也是调用了以'/n'为结束符的三参数getline()函数。
    同时当我们单步进入getline()的实现我们会发现这样的判断语句:

    [cpp:nogutter] view plaincopyprint?
    1. _Myt& __CLR_OR_THIS_CALL getline(_Elem *_Str,  
    2.                                  streamsize _Count, _Elem _Delim)  
    3. {   // get up to _Count characters into NTCS, discard _Delim  
    4.     _DEBUG_POINTER(_Str);  
    5.     ios_base::iostate _State = ios_base::goodbit;  
    6.     _Chcount = 0;  
    7.     const sentry _Ok(*thistrue);  
    8.     if (_Ok && 0 < _Count)  
    9.     {   // state okay, use facet to extract  
    10.         int_type _Metadelim = _Traits::to_int_type(_Delim);  
    11.         _TRY_IO_BEGIN  
    12.             int_type _Meta = _Myios::rdbuf()->sgetc();// 从输入流读一个字符  
    13.         for (; ; _Meta = _Myios::rdbuf()->snextc())  
    14.             if (_Traits::eq_int_type(_Traits::eof(), _Meta))  
    15.             {   // end of file, quit  
    16.                 _State |= ios_base::eofbit;// 遇到文件尾,getline结束  
    17.                 break;  
    18.             }  
    19.             else if (_Meta == _Metadelim)  
    20.             {   // got a delimiter, discard it and quit  
    21.                 ++_Chcount;  
    22.                 _Myios::rdbuf()->sbumpc();// 这句把结束符读掉了,如果不指定结束符,那就是把'/n'读掉了  
    23.                 break;  
    24.             }// 遇到结束符,getline结束,注意这里的顺序,它是先判断是否遇到结束符,后判断是否读入了指定个数的。在这里计数器仍然执行++操作  
    25.             else if (--_Count <= 0)  
    26.             {   // buffer full, quit  
    27.                 _State |= ios_base::failbit;  
    28.                 break;  
    29.             }// 读到了指定个数,执行到这里已经隐含了在指定个数的最后一位仍然不是结束符,由于在执行这部分时,在对长度计数器没有进行++操作  
    30.             else  
    31.             {   // got a character, add it to string  
    32.                 ++_Chcount;  
    33.                 *_Str++ = _Traits::to_char_type(_Meta);  
    34.             }  
    35.             _CATCH_IO_END  
    36.     }  
    37.     *_Str = _Elem();    // add terminating null character  
    38.     _Myios::setstate(_Chcount == 0 ? _State | ios_base::failbit : _State);  
    39.     return (*this);  
    40. }  

    所以在对于输入 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.

    [cpp:nogutter] view plaincopyprint?
    1. streamsize gcount( ) const;  


    Return Value
    The extraction count.
    Remarks
    Use basic_istream::get to read unformatted characters.
    Example
    1. // basic_istream_gcount.cpp  
    2. // compile with: /EHsc  
    3. #include <iostream>  
    4. using namespace std;  
    5. int main( )   
    6. {  
    7.     cout << "Type the letter 'a': ";  
    8.     ws( cin );  
    9.     char c[10];  
    10.     cin.get( &c[0],9 );// a  
    11.     cout << c << endl;// a  
    12.     cout << cin.gcount( ) << endl;// 1  注意,这里为什么是1,分析方法同getline,可以在get的实现中找的具体的原因  
    13. }   

    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

  • 相关阅读:
    计算机进制转换
    十进制二进制转换
    windows XP 下怎样查看系统运行时间总计?
    “编译器错误信息: CS0016: 未能写入输出文件”解决方法
    用ntsd关进程
    Hosts文件的位置
    开机显示client mac addr...... 错误的解决办法 .
    无法嵌入互操作类型“Microsoft.Office.Interop.Excel.ApplicationClass”。请改用适用的接口 .
    【转】XP远程桌面连接2008提示:远程计算机需要网络级别身份验证,而您的计算机不支持该验证 .
    关于Access的郁闷二三事。。。
  • 原文地址:https://www.cnblogs.com/lexus/p/2871216.html
Copyright © 2011-2022 走看看