編譯環境為: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; }
這個解釋到這里,看表面以上的字,我明白了,
但更深一層就是沒有看懂。
求解。!!~~~