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?
更多文章、技術交流、商務合作、聯系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
