對getchar()及putchar()的糾結


編譯環境為:MinGW,

系統環境:winXP

 

代碼來源《The C Programming Language (Second Edition)》:

1 while((c =getchar())!=EOF){ 2  putchar(c); 3 } 


此代碼在上述所說的書的第一章。

代碼中用到兩個函數,getchar()和putchar()。

 

我對這兩個函數剛開始很不了解,

1、getchar()的用法是怎么樣的,

2、如何讀取用戶所輸入的信息,

3、為什么每次輸入數據回車后就會執行putchar()

4、為什么每次打印出自己輸入的一行信息后不會跳出循環體

 

以上問題,有一部分有了一點的頭緒:

 

1、getchar()獲取用戶輸入數據,功能了解一點,但此問題還是沒有頭緒。

········???

 

2、如何讀取用戶輸入數據,  等待數據輸入直到回車后再打印輸入的信息,

這是代碼實現看到的,

但是,具體 的實現不了解,待添加。。

........???

 

3、代碼實現看到的,一行后自動打印此行,

EOF=='\n',這個為真??

 

4、代碼實現過程中,我只有按“Ctrl + c”才可以強制關閉。

代碼中循環體中的中止條件是:getchar() != EOF

在此時,循環體是如何中止的??

在輸入數據后打印信息,這時有沒有中止的語句讓其打印信息??

而打印數據后,又在等待用戶輸入數據。此時,又是如何讓其停止打印的??

 

 

 2012-06-22

以下是原書對上述代碼的詳解:

在該程序中,while循環語句首先讀一個字符並將其賦值給c,然后測試該字符是否為文件結束標志。如果該字符不是文件結束標志,則執行while語句體,並打印該字符。隨后重復執行while語句。當到達輸入的結尾位置時,while循環語句終止執行,從而整個main函數執行結束。

 

在此之前所涉及到的4個問題總結一下。

這里涉及到運算符的優先級、getchar()的內部運行。

首先對while循環體的條件再次解剖:( ( c = getchar() ) != EOF )

根據原文解說getchar()函數是邊輸入邊賦值,

但是我看到一篇文章說getchar()說:

getchar()有一個int型的返回值.當程序調用getchar時,程序就等着用戶按鍵.用戶輸入的字符被存放在鍵盤緩沖區中.直到用戶按回車為止(回車字符也放在緩沖區中).當用戶鍵入回車之后,getchar才開始從stdin流中每次讀入一個字符.getchar函數的返回值是用戶輸入的第一個字符的ASCII碼,如出錯返回-1,且將用戶輸入的字符回顯到屏幕.如用戶在按回車之前輸入了一止一個字符,其他字符會保留在鍵盤緩存區中,等待后續getchar調用讀取.也就是說,后續的getchar調用不會等待用戶按鍵,而直接讀取緩沖區中的字符,直到緩沖區中的字符讀完為后,才等待用戶按鍵.

這么說,( c = getchar() ),最后c的值應該是用戶輸入的第一個字符的ASCII碼,

那么,當我輸入:

abc

不回車再按“Ctrl + C”,結果是不會輸出“abc”,而是直接退出while循環。

這時,我又糾結了。。。

 

 

 

 

2012-06-23

繼續前文!

對於前文所說的,getchar()返回值為用戶輸入的第一個字符的ASCII碼,

那么c的值應該為一個字符的ASCII碼,

執行:

putchar(c); 這條語句時,為什么不是只是輸入一個字符,而是把輸入的字符都打印出來。(字符中不包括“Ctrl + z”的值)

。。。

 

 

 

 

 

2012-07-02

找到對getchar()的解釋。

 

以下宏定義是在csdn論壇上摘:

#define getchar() getc(stdin)

#define getc(_stream) ( --(_stream)->_cnt >= 0 ? 0xff & *(_stream)->_ptr++ : _filbuf(_stream) )

 

以及它的解釋:

“getchar()

它的作用是從stdin流中讀入一個字符,也就是是,如果stdin有數據的話不用輸入它就可以直接讀取了,第一次getchar()時,確實需要人工的輸入,但是如果你輸入了多個字符,以后的getchar()再執行時就會直接從緩沖區中讀取了。

實際上是:輸入設備 -> 內存緩沖區 -> 程序getchar

你按的鍵是放進緩沖區了,然后供程序getchar

你有沒有度過按住很多鍵然后等一會兒會滴滴滴滴響,就是緩沖區滿了,你的后頭按的鍵沒有存進緩沖區。

鍵盤輸入的字符都存到緩沖區內,一旦鍵入回車,getchar就進入緩沖區讀取字符,一次只返回第一個字符作為getchar函數的值,如果有循環或足夠多的getchar語句,就會依次讀出緩沖區內的所有字符直到'\n'。

要理解這一點,之所以你輸入的一系列字符被依次讀出來,就是因為循環的作用使得反復利用getchar在緩沖區里讀取字符,而不是getchar可以讀取多個字符。

事實上getchar每次只能讀取一個字符。

 

簡化以上引用的信息,也引用csdn論壇中的一句話:

“首先getchar()是個宏,而不是函數,它涉及到IO基本輸入輸出流。

 

現在的問題還剩下:

頂頭的代碼,

while循環的條件是輸入字符不等於EOF,

可是輸入任意字符串“khkseud”緊接着“Ctrl +z”回車,后再“Ctrl + z”回車,

這樣的操作才退出循環!

問:為什么第一個“Ctrl + z”不起退出循環的作用?

 

 

 

 

2012-07-03

今天,針對上一個問題得到了解釋。

這是系統調用跟蹤,來自CSDN論壇:

uname({sys="Linux", node="localhost.localdomain", ...}) = 0
fstat64(0, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 0), ...}) = 0
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb774c000
read(0, 1234"1234", 1024)                   = 4
read(0, "", 1024)                       = 0
exit_group(0)                           = ?

並引用提供該解釋的內容:

“這是系統調用跟蹤,可以看到輸入1234ctrl+d后,系統完全沒有意識到ctrl+d的

(也就是ctrl+d和沒按過是一樣的)存在阻塞在倒數第二行,再次輸入ctrl+d后才read return 0。

這不是c庫的實現問題,也不是系統API的問題,只能說是shell的問題了,因為如下也是同樣的系統調用流程:


 

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(int argc, char* const argv[]) {
        char buffer[100];
        while (read(0, buffer, 100) > 0) {

        }
        return 0;
}

 

這個解釋到這里,看表面以上的字,我明白了,

但更深一層就是沒有看懂。

 

求解。!!~~~


 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM