>,cin.get(),cin.getline(),getline這幾種輸入方法的基本使用并且進(jìn)行了其輸"/>
尹詩(shī)玉 方歡
摘要:C++是一種應(yīng)用非常廣泛的面向?qū)ο蟪绦蛟O(shè)計(jì)語(yǔ)言,該文針對(duì)C++語(yǔ)言中的各種外部輸入方法進(jìn)行了分析探討和舉例,從C++中的cin輸入流入手,主要介紹一系列輸入方法并加以測(cè)試和比較。該文首先闡釋了cin>>,cin.get(),cin.getline(),getline這幾種輸入方法的基本使用并且進(jìn)行了其輸入原理(即緩沖區(qū)存取)的探究,其次對(duì)該幾種輸入方法進(jìn)行了比較,有利于今后實(shí)際應(yīng)用中的區(qū)分,最后在實(shí)際輸入過(guò)程中會(huì)出現(xiàn)的錯(cuò)誤該文也進(jìn)行了說(shuō)明,給出了相關(guān)的問(wèn)題處理方法。
關(guān)鍵詞:C++外部輸入;輸入原理;緩沖區(qū)存??;錯(cuò)誤處理.
中圖分類號(hào):G642.0 文獻(xiàn)標(biāo)識(shí)碼:A 文章編號(hào):1009-3044(2018)04-0080-04
Discussion on Some Problems of External Input Based on C++ Language
YIN Shi-yu,F(xiàn)ANG Huan
(Anhui University of Science and Technology Institute of Mathematics and Big Date, Huainan 232001, China)
Abstract: C++ is an object oriented programming language that is widely used,This paper analyzes and discusses various external input methods in C++ language, starting with the CIN input stream in C++, mainly introduces a series of input methods, and tests and compares them. This paper explains cin>>, cin.get (cin.getline), (getline), the basic use of this input method and its input several principle (i.e. buffer access) inquiry, then the several access methods are compared, which helps to identify future practical application, finally in the actual input process will appear the error in this paper is also described, given relevant treatment problems.
Key words: C++ external input; input principle; buffer access; error handling
1 背景
計(jì)算機(jī)是一種信息處理機(jī)器,它的主要工作就是處理各種信息和數(shù)據(jù)。 而信息不可能都是由計(jì)算機(jī)自己生成的,因此多數(shù)實(shí)際應(yīng)用的程序都需要有將用戶的信息輸送給計(jì)算機(jī)的功能。 同時(shí),計(jì)算機(jī)的最終運(yùn)算結(jié)果必須以某種方式呈現(xiàn)出來(lái)以供用戶查看。一般說(shuō)來(lái),一個(gè)具有實(shí)際應(yīng)用價(jià)值的程序必須具備輸入輸出功能[1]。C++語(yǔ)言作為C語(yǔ)言的延伸和發(fā)展,其中提供的I/O流有一個(gè)明顯的優(yōu)點(diǎn),就是程序設(shè)計(jì)人員可以不考慮數(shù)據(jù)的類型,而直接使用cin>>a;來(lái)從鍵盤(pán)中提取數(shù)據(jù),>>即為提取操作符,而C語(yǔ)言必須明確表示出變量的數(shù)據(jù)類型[3]。經(jīng)過(guò)C++語(yǔ)言的學(xué)習(xí),筆者發(fā)現(xiàn)書(shū)中對(duì)待不同的問(wèn)題采用的外部輸入方式也不相同,例如cin>>,cin.get(),cin.getline(),getline,等方法,然而書(shū)中卻沒(méi)有給出深入的闡釋與區(qū)分。現(xiàn)很少有文獻(xiàn)全面總結(jié)了C++語(yǔ)言中各種輸入函數(shù)的用法,因此本文將從C++輸入流出發(fā),在ANSI C2.0環(huán)境下分析和研究各種輸入方法適用的情況,并進(jìn)行相關(guān)的對(duì)比及區(qū)分,本文所給代碼均經(jīng)過(guò)DEV-C++5.4.0編譯通過(guò)。
2 常見(jiàn)的C++輸入方式及其原理
C++輸入即如何給程序提供數(shù)據(jù),cin對(duì)象將標(biāo)準(zhǔn)輸入表示為字節(jié)流,通常情況下,通過(guò)鍵盤(pán)來(lái)生成這種字符流。
流:C++的程序把輸入和輸出看做字節(jié)流。cin是標(biāo)準(zhǔn)輸入流,輸入時(shí),程序從輸入流中抽取字節(jié);輸出時(shí),程序?qū)⒆止?jié)插入輸出流中,流充當(dāng)了程序和流源或流目標(biāo)之間的橋梁。
緩沖區(qū):緩沖區(qū)是用作中介的內(nèi)存塊,它是將信息從設(shè)備傳輸?shù)匠绦蚧蛘邚某绦騻鬏數(shù)皆O(shè)備的臨時(shí)存儲(chǔ)工具,用以匹配程序和設(shè)備之間速率的差距[2]。
C++程序的輸入輸入原理如下:鍵盤(pán)每一次的輸入結(jié)束都會(huì)把數(shù)據(jù)存入輸入緩沖區(qū),若緩沖區(qū)中存在數(shù)據(jù)內(nèi)容則下一次會(huì)從緩沖區(qū)直接提取而不會(huì)由鍵盤(pán)輸入。
2.1 cin>>的用法
[用法]由圖1和圖2可知cin>>是接收一個(gè)字符串,且遇“空格”,“TAB”,“回車”都結(jié)束提取過(guò)程。此外cin還有一個(gè)基本的用法即接收一個(gè)數(shù)字,用cin>>a接收,這里便不再具體用程序解讀。
[原理]該操作符是根據(jù)后面變量的類型讀取數(shù)據(jù);輸入結(jié)束條件為:Enter,Space,Tab鍵;對(duì)結(jié)束符的處理為:丟棄緩存區(qū)中的結(jié)束符。
[分析] 第一次讀取字符串時(shí)遇到空格停止了,將abc讀入str1,def則存入緩沖區(qū),然后從緩沖區(qū)提取了def給了第二個(gè)字符串,這證明了cin>>丟棄了空格符,將后面字符存入緩沖區(qū),之后直接從緩沖區(qū)中取數(shù)據(jù)。
2.2 cin.get()的使用
該輸入方式有4種形式,無(wú)參,一個(gè)參數(shù),二個(gè)參數(shù),三個(gè)參數(shù)。無(wú)參數(shù)char ch=cin.get()等價(jià)于有1個(gè)參數(shù)cin.get(char ch);2個(gè)參數(shù)cin.get(數(shù)組名,長(zhǎng)度),則最后一個(gè)結(jié)束符默認(rèn)為Enter鍵;3個(gè)參數(shù)cin.get(數(shù)組名,長(zhǎng)度,結(jié)束字符)。
2.2.1 cin.get(無(wú)參數(shù))的用法
1) 實(shí)驗(yàn)程序
[用法]由上述實(shí)驗(yàn)可知cin.get(ch)即用來(lái)接收一個(gè)字符,且char ch=cin.get()等價(jià)于cin.get(char ch)。
2) 原理解讀
[原理]1個(gè)參數(shù)時(shí)結(jié)束符默認(rèn)為Enter,若要讀取字符,直接cin.get()或ch=cin.get()即可;輸入結(jié)束條件:Enter鍵;對(duì)結(jié)束符處理:不丟棄緩沖區(qū)中的結(jié)束符。
[分析一] 有程序運(yùn)行結(jié)果及ASCII碼值可知第一個(gè)數(shù)據(jù)取的‘a(chǎn),第二個(gè)變量取的是回車,這是因?yàn)樵撦斎敕绞讲粊G棄上次輸入結(jié)束時(shí)的回車符,所以緩沖區(qū)中殘留了回車符。
[分析二] 顯然第一個(gè)數(shù)據(jù)取的‘a(chǎn),第二個(gè)數(shù)據(jù)取的是空格(ASCII為32)。說(shuō)明在輸出‘a(chǎn)之后,直接從緩沖區(qū)調(diào)取了空格,證明沒(méi)有丟棄Space字符,保存在了緩沖區(qū)。
2.2.3 cin.get(字符數(shù)組名,接受字符數(shù)目,結(jié)束字符)的用法
2 個(gè)參數(shù)cin.get(數(shù)組名,長(zhǎng)度)等價(jià)于3個(gè)參數(shù)cin.get(數(shù)組名,長(zhǎng)度,結(jié)束字符)中最后一個(gè)結(jié)束符默認(rèn)為Enter鍵,這里便將兩者的用法合并探究。
1) 實(shí)驗(yàn)程序
[用法]cin.get(字符數(shù)組名,接受字符數(shù)目,結(jié)束字符)其中結(jié)束字符可以自定義,若缺省則默認(rèn)為Enter鍵,用來(lái)接收一行字符串,可以接收空格,但接受字符個(gè)數(shù)為長(zhǎng)度-1,最后一個(gè)默認(rèn)為‘\0。
2) 原理解讀
[原理]輸入結(jié)束條件:默認(rèn)Enter鍵,可以自定義結(jié)束符;對(duì)結(jié)束符的處理:丟棄緩沖區(qū)的默認(rèn)結(jié)束符Enter,自定義時(shí)不丟棄。
[分析一]第一次輸入字符過(guò)長(zhǎng),字符串按定義的5個(gè)長(zhǎng)度取了4個(gè)數(shù)‘1234,而‘5存入了緩沖區(qū)中,所以第二次輸入字符沒(méi)有從鍵盤(pán)讀入,而是直接取了‘5,所以輸出的是‘5的ASCII碼值53.
[分析二] 由于結(jié)束符為‘b,故只取了之前的12,第二次輸出為b,說(shuō)明自定義結(jié)束符時(shí)不會(huì)丟棄緩沖區(qū)中的結(jié)束符。
2.3 cin.getline()的用法
1) 實(shí)驗(yàn)程序
[原理]該輸入方式與cin.get(字符數(shù)組名,接受字符數(shù)目,結(jié)束字符)大致相同,但是cin.getline()當(dāng)輸入過(guò)長(zhǎng)時(shí),會(huì)出現(xiàn)錯(cuò)誤,后面的cin操作將不再執(zhí)行。
[分析]這里并沒(méi)有讀取緩沖區(qū)的‘5,而是返回了0,因?yàn)閏in出錯(cuò)了。
2.4 getline()的用法
getline()接收一個(gè)字符串,可以接收空格,需要包含#include
1) 實(shí)驗(yàn)程序
[分析]getline的讀取原理是將以‘\n為結(jié)束符作為一完整讀取的一行,‘\n會(huì)讀取。所以當(dāng)之前用cin是C++ string中的,因?yàn)閏in無(wú)法輸入空格從而有了getline讀取一行,回車作為結(jié)束,回車也讀取。
3 有關(guān)的輸入方式的比較
[分析]用戶如果給出兩個(gè)合法的數(shù),程序會(huì)正確執(zhí)行,而當(dāng)給出一個(gè)不合法字符‘a(chǎn)時(shí)程序便不再執(zhí)行cin。
4.2 cin.getline()超長(zhǎng)導(dǎo)致的錯(cuò)誤
見(jiàn)圖17中的程序
[分析]因?yàn)間etline以‘\n作為結(jié)束符,故當(dāng)前面用cin讀取一個(gè)字符的時(shí)候,會(huì)輸入字符后點(diǎn)擊回車,此時(shí)getline會(huì)自動(dòng)讀取這個(gè)回車,程序便不再請(qǐng)求從鍵盤(pán)輸入。此錯(cuò)誤可在getline之前用cin.ignore()來(lái)解決。
4.4 cin的問(wèn)題處理
其實(shí)在編程過(guò)程中很多時(shí)候都會(huì)遇到諸如此類的錯(cuò)誤,多數(shù)問(wèn)題是由于cin特殊的使用原理即緩沖區(qū)存取造成的,下面筆者將簡(jiǎn)單介紹解決這些錯(cuò)誤即清除緩沖區(qū)的幾種方法。在程序中經(jīng)常出現(xiàn)的cin.ignore(),cin.clear(),cin.fail(),cin.sync()這些函數(shù),其實(shí)都與cin的錯(cuò)誤處理有關(guān)。
4.4.1 cin.clear()
作用:清除cin流的錯(cuò)誤狀態(tài),將錯(cuò)誤標(biāo)識(shí)改為默認(rèn)0。
還是圖17程序中cin.getline()超長(zhǎng)出現(xiàn)的錯(cuò)誤為例。解決方法便是在cin.getline()之后加上cin.clear(),則程序便讀取了緩沖區(qū)的5,并輸出了其ASCII碼值53,解決了相關(guān)錯(cuò)誤,由此可看出cin.clear()并沒(méi)有清空緩沖區(qū)。
cin.clear()通常和cin.sync()結(jié)合使用來(lái)解決類型輸入錯(cuò)誤問(wèn)題,cin.clear()默認(rèn)參數(shù)為0,即無(wú)錯(cuò)誤的正常操作。當(dāng)我們輸入類型錯(cuò)誤時(shí)時(shí),它的狀態(tài)標(biāo)識(shí)為fail,即錯(cuò)誤,用cin.clear()先將錯(cuò)誤標(biāo)識(shí)改為0之后用cin.sync()清空數(shù)據(jù)流再繼續(xù)輸入正確的類型則能正確輸出。
4.4.2 cin.sync()
作用:清除緩沖區(qū)的數(shù)據(jù)流。
由于cin在遇到空格時(shí),就會(huì)停止輸入,所以如果我在第一次輸入時(shí),利用空格隔開(kāi)兩個(gè)字符串,那么cin在第一次取的時(shí)候,只會(huì)讀取前一個(gè)字符串,到空格結(jié)束,此時(shí)緩沖區(qū)還保留著前面輸入的第二個(gè)字符串,那么第二次cin就會(huì)直接從緩沖區(qū)取殘留數(shù)據(jù),而不會(huì)請(qǐng)求輸入。對(duì)于以上的情況解決的方案,就是在第二次調(diào)用cin>>str之前通過(guò)cin.sync()來(lái)清空輸入緩沖區(qū)。
4.4.3 cin.ignore()
作用:用來(lái)清除以回車結(jié)束的輸入緩沖區(qū)的內(nèi)容。
cin.ignore()的作用是丟棄緩沖區(qū)的第一個(gè)字符,這在程序中也是比較常用的,程序中用cin.get()來(lái)讀取字符,第一次讀取時(shí)用回車結(jié)束,有上文的介紹可知,回車殘留在緩沖區(qū),會(huì)導(dǎo)致第二次直接從緩沖區(qū)取得回車符,而cin.ignore()則丟棄了緩沖區(qū)中的回車符,此時(shí)緩沖區(qū)是空的,故會(huì)請(qǐng)求從鍵盤(pán)輸入。
在getline之前用cin進(jìn)行讀取的時(shí)候,由于getline以‘\n作為結(jié)束符,故當(dāng)前面用cin讀取一個(gè)字符的時(shí)候,會(huì)輸入字符后點(diǎn)擊回車,此時(shí)getline會(huì)自動(dòng)讀取這個(gè)回車,并判斷結(jié)束了,用cin.ignore()將緩沖區(qū)清除后,程序便會(huì)請(qǐng)求從鍵盤(pán)輸入提取,故可輸出了。
5 結(jié)束語(yǔ)
本文通過(guò)對(duì)各種C++輸入方法及其緩沖區(qū)原理的總結(jié),更有助于以后程序設(shè)計(jì)過(guò)程中熟練的運(yùn)用各種輸入函數(shù)并加以區(qū)分。C++語(yǔ)言編程技術(shù)作為C語(yǔ)言編程的延伸和發(fā)展,能夠更好的為計(jì)算機(jī)編程服務(wù),更好的滿足現(xiàn)代化發(fā)展需求。充分理解并且熟練掌握C++語(yǔ)言中的輸入方式更是編程的基礎(chǔ)。本文通過(guò)實(shí)例進(jìn)行分析和總結(jié),為以后的編程打下了堅(jiān)實(shí)的基礎(chǔ)。
參考文獻(xiàn):
[1] 姜靈敏. 緩沖機(jī)制及C++輸入/輸出[J]. 新課程研究:中旬刊, 2013(2):81, 84.
[2] STEPHEN PRATA.C++ Primer Plus[M]. 張海龍, 袁國(guó)忠, 譯. 北京: 人民郵電出版社, 2012.
[3] 張富編. C及C++程序設(shè)計(jì)[M]. 3版. 北京: 人民郵電出版社, 2008.