代碼如下
--------------------------------------------------------------
int main()
{
char ch;
int count = 0;
cin.get(ch);
while (cin.fail()==false)
{
cout<<ch;
count++;
cin.get(ch);
}
cout<<"\n"<<count<<"characters read\n";
return 0;
}
---------------------------------------------------------
VC6.0控制台模式下(^z在VC中模拟檔案尾)
為什麼輸入一串字元加^z後,回車,程式不會結束??!!
比如輸入:abcd^z 回車
程式回顯 abcd
按道理
當讀到^z時,檢測到了檔案尾,cin将eofbit,failbit都設為1
假如eofbit或failbit設為1,cin.fail則傳回true,應該結束程式了,調試中為什麼不結束?
輸入:abcd 回車
程式回顯:abcd 換行符(看不見),然後等待輸入,此時按下^Z 回車可以
為什麼上一種情況不可以?
困惑,尋找解答,謝謝!!
答案:
原因分析如下:
輸入緩沖是行緩沖。當從鍵盤上輸入一串字元并按回車後,這些字元會首先被送到輸入緩沖區中存儲。每當按下Enter鍵後,cin.get() 就會檢測輸入緩沖區中是否有了可讀的資料。cin.get()還會對鍵盤上是否有作為流結束标志的 Ctrl+Z或者 Ctrl +D 鍵按下作出檢查,其檢查的方式有兩種:阻塞式以及非阻塞式。
阻塞式檢查方式指的是隻有在Enter鍵按下之後才對此前是否有Ctrl Z組合鍵按下進行檢查,非阻塞式樣指的是按下Ctrl D 之後立即響應的方式。假如在按Ctrl D之前已經從鍵盤輸入了字元,則Ctrl D的作用就相當于回車,即把這些字元送到輸入緩沖區供讀取使用,此時Ctrl D不再起流結束符的作用。假如按Ctrl D之前沒有任何鍵盤輸入,則Ctrl D就是流結束的信号。
Windows系統中一般采用阻塞式檢查Ctrl Z、Unix/Linux系統下一般采用非阻塞式的檢查Ctrl D。樓主是在Windows系統下,是以使用阻塞式的Ctrl Z 來辨別流的結束。
這種阻塞式的方式有一個特點:隻有按下回車之後才有可能檢測在此之前是否有Ctrl Z按下。還有一個特點就是:假如輸入緩沖區中有可讀的資料則不會檢測Ctrl Z(因為有要讀的資料,還不能認為到了流的末尾)。還有一點需要知道:Ctrl Z産生的不是一個普通的ASCII碼值,也就是說它産生的不是一個字元,是以不會跟其它從鍵盤上輸入的字元一樣能夠存放在輸入緩沖區。明白了這幾點之後就可以來解釋樓主提出的問題了。
從鍵盤上輸入abcd^z加回車之後在Windows系統上是這樣處理的:由于回車的作用,前面的abcd等字元被送到輸入緩沖區(注意:上面說過了,^z不會産生字元,是以更不會存儲到輸入緩沖區,緩沖區中沒有^z的存在)。這時,cin.get()檢測到輸入緩沖區中已經有資料存在(是以不再檢查是否有^z的輸入),于是從緩沖中讀取相應的資料。假如都讀取完了,則輸入緩沖區重新變為空, cin.get()等待新的輸入。可見,盡管有^z按下,但是由于在此之前還有其它輸入字元(abcd),是以流也不會結束。
是以,輸入流結束的條件就是:^z之前不能有任何字元輸入(回車除外),否則^z起不到流結束的作用。
還有個問題
假如輸入abcd^zabcd
程式回顯 abcd
并等待輸入,也就是^Z後的不再顯示了
-----------------------------------------------
假如輸入緩沖區中有可讀的資料則不會檢測Ctrl Z(因為有要讀的資料,還不能認為到了流的末尾)。還有一點需要知道:Ctrl Z産生的不是一個普通的ASCII碼值,也就是說它産生的不是一個字元,是以不會跟其它從鍵盤上輸入的字元一樣能夠存放在輸入緩沖區。
假如輸入abcd^zabcd
程式回顯 abcd
并等待輸入,也就是^Z後的不再顯示了
為什麼後面的卻沒有處理呢?
是以可以把這種情況下的^z了解為鍵盤輸入的終止,但不是流的終止
--------------------------------------------------------------------------------------------
不過我認為答複仍然沒有解決我的疑問。假如當程式提示"please enter the first data"時,直接輸入^Z。按照2樓或return0x0朋友給出的方法,由于輸入緩沖區中沒有可讀的資料,則會檢測Ctrl Z。可是,實際情況是此時輸入的^Z并未終止程式的運作,仍然需要再輸一遍^Z才能中止程式。這是為什麼呢?
4樓的朋友可能用的是VC2003,正如hai040朋友說的:
vc2003,一次就行
before input, current err state is:0
please enter the first data
^Z
The first data is -858993460
after input the first data, current err state is:3
Press any key to continue
我用的是VC 6.0 轉載:http://lipingke.blog.hexun.com/40431101_d.html