1.getchar()是標準I/O標準庫里的庫函數(shù) 原型是int getchar(void)-----------它沒有參數(shù),原因是因為它是從stdin標準輸入流中讀入一個字符的函數(shù),已經有了默認的流參數(shù)stdin了。其返回值是一個整型數(shù),是用來表示字符用的。 輸入輸出往往都是內存與外設之間的數(shù)據來往,但是,內存的運行效率比外設的運行效率那要大得多,比如,從內存寫一個字符到磁盤上,內存很快地傳出字符數(shù)據,供給磁盤存儲,磁盤花了很多的時間來存儲,在這段存儲的時間里,我們寶貴的內存只能干等著磁盤做完存儲操作來傳遞下一個字符,這樣的做法是非常浪費內存的。所以計算機牛人們就設計出了緩沖的概念,來緩和內存與外設之間速度不匹配的問題。這意味著程序的輸入輸出已經不是跟外設直接打交道了,而是從一塊被稱為緩沖區(qū)的內存區(qū)域來回復制數(shù)據。就C程序而言,所有的IO操作只是簡單地從程序移進移出字節(jié),這種字節(jié)流即為流。 回到getchar()函數(shù)中來,我們以下面一個程序為例。 #include<stdio.h> 第一種情況:如果你的輸入只有一個字符,那么肯定的,ch1的值便是這個字符,那么ch2呢?在這里別忘了,你輸完前一個字符后是通過什么結束輸入的?是的,是Enter,Enter肯定會說:“人家可也是個正正經經的字符啊,不要不把無字幕的字符不當字符??!”是的,在這里是向緩沖區(qū)中輸入了兩個字符,而getchar()是做什么呢?前面提到了,程序可不是直接跟外設打交道的,而是跟緩沖區(qū)打交道的,所以,getchar()庫函數(shù)是從緩沖區(qū)中讀取字符而不是從鍵盤讀取字符的,所以,你已經向緩沖區(qū)中輸入了兩個字符夠上面程序中兩個getchar()讀的了。可以用下面的程序測試一下這種效果。
如果在第一次輸入的時候不是簡單的輸入一個字符和一個換行,而是輸入了一大堆字符,那么,這些字符將全部送往stdin流的緩沖區(qū)中,后面的所有包括getchar()的將從stdin流中讀入數(shù)據的庫函數(shù)將從這個緩沖區(qū)中讀入數(shù)據,直道緩沖區(qū)再次為空后,才提示輸入設備準備輸入數(shù)據。 一、getchar的兩點總結: while((c = getchar()) != EOF){ 執(zhí)行程序,輸入:abc,然后回車。則程序就會去執(zhí)行puchar(c),然后輸出abc,這個地方不要忘了,系統(tǒng)輸出的還有一個回車。然后可以繼續(xù)輸入,再次遇到換行符的時候,程序又會把那一行的輸入的字符輸出在終端上。
對這個問題的一個解釋是,在大師編寫C的時候,當時并沒有所謂終端輸入的概念,所有的輸入實際上都是按照文件進行讀取的,文件中一般都是以行為單位的。因 此,只有遇到換行符,那么程序會認為輸入結束,然后采取執(zhí)行程序的其他部分。同時,輸入是按照文件的方式存取的,那么要結束一個文件的輸入就需用到EOF (Enf Of File). 這也就是為什么getchar結束輸入退出時要用EOF的原因。 2.getchar()的返回值一般情況下是字符,但也可能是負值,即返回EOF。 這里要強調的一點就是,getchar函數(shù)通常返回終端所輸入的字符,這些字符系統(tǒng)中對應的ASCII值都是非負的。因此,很多時候,我們會寫這樣的兩行代碼: 這樣就很有可能出現(xiàn)問題。因為getchar函數(shù)除了返回終端輸入的字符外,在遇到Ctrl+D(Linux下)即文件結束符EOF時,getchar ()的返回EOF,這個EOF在函數(shù)庫里一般定義為-1。因此,在這種情況下,getchar函數(shù)返回一個負值,把一個負值賦給一個char型的變量是不 正確的。為了能夠讓所定義的變量能夠包含getchar函數(shù)返回的所有可能的值,正確的定義方法如下(K&R C中特別提到了這個問題): 二、EOF的兩點總結(主要指普通終端中的EOF) EOF雖然是文件結束符,但并不是在任何情況下輸入Ctrl+D(Windows下Ctrl+Z)都能夠實現(xiàn)文件結束的功能,只有在下列的條件下,才作為文件結束符。 2.EOF作為行結束符時的情況,這時候輸入Ctrl+D并不能結束getchar(),而只能引發(fā)getchar()提示下一輪的輸入。 這種情況主要是在進行getchar()新的一行輸入時,當輸入了若干字符(不能包含換行符)之后,直接輸入Ctrl+D,此時的Ctrl+D并不是文件 結束符,而只是相當于換行符的功能,即結束當前的輸入。以上面的代碼段為例,如果執(zhí)行時輸入abc,然后Ctrl+D,程序輸出結果為: 注意:第一組abc為從終端輸入的,然后輸入Ctrl+D,就輸出第二組abc,同時光標停在第二組字符的c后面,然后可以進行新一次的輸入。這時如果再次輸入Ctrl+D,則起到了文件結束符的作用,結束getchar()。 從這里也可以看出Ctrl+D和換行符分別作為行結束符時,輸出的不同結果。 EOF的作用也可以總結為:當終端有字符輸入時,Ctrl+D產生的EOF相當于結束本行的輸入,將引起getchar()新一輪的輸入;當終端沒有字符 輸入或者可以說當getchar()讀取新的一次輸入時,輸入Ctrl+D,此時產生的EOF相當于文件結束符,程序將結束getchar()的執(zhí)行。 順便提一下輸出庫函數(shù)。輸出庫函數(shù)的效果也只是將程序中的內容輸出到緩沖區(qū)中,然后再刷新的時候輸出到外設上,如果在輸出的時候輸出輸出流stdout緩沖區(qū)中已經有了數(shù)據,那么輸出的是已經有的內容,而不一定是你輸出的內容。這是由緩沖區(qū)刷新的時間控制的,刷新的操作是根據具體的編譯器來決定的,一般調用fflush(stdout)來刷新一下stdout緩沖區(qū)。 |
|