C 處理檔案結束符的兩種不同方式

2021-07-15 08:30:47 字數 1812 閱讀 9760

首先來看一下下面這小段**:

#include

#include

#include

int main()

裡面while一直檢查輸入流的狀態,知道接收到檔案結束符(在windows上面是ctrl+z 在linux/unix上面是ctrl+d)或錯誤輸入,但是當輸完多個字元再加上乙個檔案結束符再按enter的時候,發現輸入流並沒有停止請求輸入,而是一直等待使用者繼續輸入:

直到在按下ctrl+z之前沒有任何字元輸入程式才會結束。

把string換成char,結果也一樣:

而再把型別換成int:

結果則不一樣,在輸入數字1後直接ctrl+z,程式就結束了,把int換成其它的整形、浮點型結果都是一樣的。

這就說明,輸入流處理檔案結束符的方法對字元字串和算術型別的還是不一樣的。

在網上找到了一點原因分析:

當從鍵盤輸入一串字元並按回車後,這些字元會首先被送到輸入緩衝區中儲存。每當按下回車鍵後,cin.get()就會檢測輸入緩衝區中是否有了可讀的資料。cin.get()還會對鍵盤上是否有流結束標識的ctrl-z或者ctrl-d鍵按下做出檢查,其檢查的方式有兩種,阻塞式以及非阻塞式。

windows系統一般採用阻塞式檢查ctrl-z,unix/linux系統下一般採用非阻塞式的檢查ctrl-d.

阻塞式檢查方式是指只有在回車鍵按下之後才對此前是否有ctrl-z組合鍵按下進行檢查。另外,如果輸入緩衝區中有可讀的資料則不會檢測ctrl-z,因為有可讀資料,說明還未到流的末尾。需要注意的時,ctrl-z產生的不是乙個普通的ascii字元,因此ctrl-z不會跟其它從鍵盤輸入的字元一樣能夠存放在輸入緩衝區中。因此,若要使ctrl-z產生作用,輸入ctrl-z之前不應輸入任何字元,即輸入回車鍵把之前輸入的字元全部送入緩衝區中後,緊接著應輸入ctrl-z,然後輸入回車鍵,告知系統檢測流結束符ctrl-z.

非阻塞式是指按下ctrl-d之後立即響應的方式。如果在ctrl-d輸入之前已經從鍵盤輸入了字元,則ctrl-d相當於回車,即把這些字元送到了輸入緩衝區供讀取使用,此時ctrl+d不再起流結束符的作用。若ctrl-d輸入之前沒有任何鍵盤輸入,則ctrl-d就是流結束的訊號。

windows 下ctrl-z使用舉例說明如下:

從鍵盤上輸入abcd^z 再輸入回車鍵後,系統處理如下:因為回車的作用,前面的abcd等字元被送到輸入緩衝區中,而^z不會產生字元,因此不會儲存到緩衝區中。這時,cin.get()檢測到輸入緩衝區中已經有資料存在,就不會檢測有無^z存在,cin.get()從緩衝中讀取相應的資料,如果讀取完了,則輸入緩衝區重新變為空,cin.get()等待新的輸入,可見儘管有ctrl-z輸入,但是之前有其它字元,系統並未監測到流結束符。

因此輸入流結束符的條件就是:^z之前不能有任何字元輸入(回車鍵除外),然後再用回車鍵通知系統做流結束符檢測。

而對於處理算術型別的,任何情況下,只要把檔案結束符送到緩衝區,輸入流就會檢測到並結束接收輸入。

C 中的檔案結束符

int main 控制台輸入多個字串後,輸入檔案結束符crtl z,並未使while迴圈結束,該如何跳出while迴圈?解決方法 方法1 回車 ctrl z 回車方法2 改 設定自己的檔案結束符 string a while cin a a x x可以為自己設定的檔案結束符。原因解析 當從鍵盤輸入一...

使用 awk 生產表的兩種不同方式

awk 可以用於解決重複性高的任務,核心在於使用 awk 來批量的生成需要的表。這裡的表既可以是特定的格式設定,如圖形介面中的 style 也可以是 或者其它。這裡我以圖形介面中的 style 為例。當我需要對多個功能不同,操作方式相同的 checkbutton 指定不同的 style 來完成各自不...

定義字元陣列的兩種不同方式的區別

由於c語言中沒有字串型別,所以用char陣列代字串型別,定義字元陣列的方式有兩種,下面來看它們的區別 方式一 以單字元形式 要宣告初始化乙個可儲存四個有效值的字元陣列,形式如下 char chararray 4 方式二 以字串形式 要宣告乙個可儲存四個有效值的字元陣列,形式如下 char strin...