(七十七)迴圈和文字輸入 EOF

2021-07-08 16:05:02 字數 4497 閱讀 9517

上**:

//讀取使用者輸入,到某乙個字元為止,並計數

#includeint main()

cout << " 對吧。共計有" << a << "個字元(包含空格等字元)。" << endl;

system("pause");

return 0;

}

輸出:

enter a word and end with '#':

wang dong#

你輸入的是 wang dong 對吧。共計有9個字元(包含空格等字元)。

請按任意鍵繼續. . .

總結:①利用char型別一次只能讀取乙個字元的特點,逐個讀取使用者輸入(後放到快取區)的字元。

②每次讀取後,這樣的迴圈形式。

以讀取到『#』字元,判斷是否結束迴圈。

因此讀取到#字元,所以可以無需再次輸出字元(此時若輸出,則輸出的是#字元)。

③每次執行迴圈——即讀取到乙個非#字元,

則記錄讀取字元數的變數+1。

++a也可以寫成a++,或者a=a+1

④程式的邏輯是這樣的(無說明,則按順序向下執行):

(1)要求使用者輸入乙個字元;

(2)使用者是否輸入字元,未輸入跳(2.1),輸入跳(3)

(2.1)cin只讀取非空格/換行/tab字元,要求使用者繼續輸入。沒輸入繼續跳(2.1),輸入了跳(3)

(3)將使用者輸入的儲存到快取區,然後被cin讀取乙個字元;

(4)進入while部分,先判斷,讀取的是否是#字元,是,跳(end),不是,跳(5)

(5)輸出讀取的字元;

(6)計數器+1——因為讀取到乙個非#字元;

(7)讀取下乙個字元,若讀取不到,則要求使用者輸入字元,跳(4)

(end)輸出計數器的數字(讀取到的非#的字元的數量),且此時已經輸出了#前的所以字元。

假如使用者輸入了幾個字元,但未輸入#字元,那麼先正常執行,到讀取不到字元為止,此時是(7),要求使用者繼續輸入字元,假如使用者沒輸入#,輸入了其他,繼續迴圈(4)~(7),假如輸入了#字元,跳到(4)後結束迴圈,跳到(end)。

注:問題在於,使用者若未按要求輸入#作為結尾,計數器沒問題,但最後排版會出問題。

捨棄掉快取區無用的字元(剩餘的所有字元)

⑤假如需要兩次判斷這些語句。而使用者又輸入了比如abc#def。那麼在讀取完abc#後,def依然留在快取區之中。

如果需要第二次判斷,那麼就需要用乙個getline(cin,string型別變數名),讀取掉快取區的所有字元,只剩下最後的換行字元。然後,第二次可以如同這樣繼續。

之所以用getline,和string型別,是因為只有這樣才能確保讀取掉快取區所有字元(包括空格,換行符等)而cin>>則不會讀取空格,換行符等,假如剩餘字元中有這些字元,那麼就不會讀取完所有字元。

例如,使用者輸入abc#def,

第一次判斷讀取到abc#,然後快取區剩下def。

於是,第二部分,直接讀取了def,還有f後面的換行符(即4個字元),然後發現沒有#作為結尾,要求使用者繼續輸入。

於是,加入兩行**:

string ddd; //string型別變數ddd,用於讀取不符合要求的資訊

getline(cin,ddd); //讀取掉快取區剩餘的所有字元,包括最後的換行符也捨棄掉。

這兩行**讀取掉了def,和最後的換行符。

在進入下一部分正常讀取之後,cin發現快取區無東西可讀,於是要求使用者輸入字元。

於是就進入了正常迴圈之中。

如**:

//讀取使用者輸入,到某乙個字元為止,並計數。此種行為重複兩次

#include#includeint main()

cout << " 對吧。共計有" << a << "個字元(包含空格等字元)。" << endl;

string ddd; //string型別變數ddd,用於讀取不符合要求的資訊

getline(cin,ddd); //讀取掉快取區剩餘的所有字元,包括最後的換行符也捨棄掉。

char word1; //char型別,決定一次只能讀取乙個字元

int b = 0;

cout << "enter a word and end with '#': " << endl;

cin >> word1; //因為型別為char,所以cin只讀取了使用者輸入的第乙個字元,其餘字元還在緩衝區之中,未被讀取

cout << "你輸入的是 ";

while (word1 != '#') //注意,不能用空字元\0來替代

cout << " 對吧。共計有" << b << "個字元(包含空格等字元)。" << endl;

system("pause");

return 0;

}

輸出:

enter a word and end with '#':

a b # c d # e f#

你輸入的是 a b 對吧。共計有4個字元(包含空格等字元)。

enter a word and end with '#':

b c#

你輸入的是 b c 對吧。共計有3個字元(包含空格等字元)。

請按任意鍵繼續. . .

注意:輸出第三行的b後面有乙個空格字元,其他是排版預留的空格字元。

eof:

還是沒搞懂,大概總結總結吧。

eof是檔案尾,

很多作業系統都支援用鍵盤模擬檔案尾(比如window是ctrl+z)。

編譯器檢測到檔案尾之後,cin將(eofbit和failbit)設為1。然後可以通過eof()來檢視eofbit是否為1。如果是1,則eof()返回true。

cin.eof()則是檢測cin輸入的內容的eof是不是為1。

當cin.eof()檢測到eof後,於是將返回true

若和其他字元一起輸入,ctrl+z不會被認為是eof(比如我輸入abc然後ctrl+z回車,輸出的是abc和->,->是乙個字元) ,只有單獨輸入的時候,才會被認為是eof。然後cin.eof()==true了。

檢測到eof後,cin將不再讀取輸入了。

部分系統可以用cin.clear()來清理掉eof標記。從而cin可以繼續讀取輸入。

在while(cin)這行**裡,cin是檢測是否能讀取——或者說是否遇見檔案尾,沒遇見,則能讀取,返回值true——繼續迴圈。遇見,不能讀取,返回false(0),停止迴圈。

————注意,判斷語句實際上是根據表示式的返回值,為true則執行迴圈,否則停止。

迴圈語句也可以改為:

char word;	//char型別,決定一次只能讀取乙個字元

int a = 0;

cout << "enter a word and end with '#': " << endl;

while (cin.get(word))a++;

效果同之前的。即:

(1)讀取快取區,賦值給word變數(cin.get(word);

(2)能讀取,返回值true,執行迴圈體(a++),迴圈體也可以為空;

(3)不能讀取,返回值flase(需要通過ctrl+z來關閉cin,才不能讀取);

(4)假如沒有遇見eof,那麼cin.get(word)要求使用者繼續輸入。

不用eof的話,改為**:

//效果是遇見換行符停止讀取,並輸出字元

int a = 0;

cout << "enter a word and end with : " << endl;

while (cin.get(word))

注:①word=10表示遇見換行符(ascii值為10)執行後面的迴圈語句。

②if (word == 10)break;這行**的意思是,當檢測到輸入的字元為換行符時,破壞迴圈(即結束迴圈)。

③break是退出當前迴圈(注意,if這一行語句不是迴圈)。即結束while這乙個迴圈。但不結束所有迴圈。

且break語句後面的迴圈都不再執行。

eof在判斷語句的時候,可以直接用不帶雙引號的「eof」作為判斷語句,例如

while(word!=eof){},則是word讀取到的字元不是eof的時候,則執行迴圈,讀取到eof,則停止迴圈。——!=表示不等於

有時候,char型別不支援,需要改為:

int a;  //事先宣告乙個int變數a

char word; //char型別word變數用於讀取字元

while ((a=word)!=eof){}

效果同上面

但總的來說!!對eof還是很暈啊!!!!

cin的幾個變種:

①假如首先char a;

然後a=cin.get()和cin.get(a)是一樣效果的。

②假如char a變為int a,那麼cin.get(a)就無法使用了。而a=cin.get()是可以使用的,但是返回的是int值(因為a是int型別);

用迴圈進行文字輸入,EOF的使用

選擇乙個特殊字元作為結束字元,有時候被稱為哨兵字元。include using namespace std int main cout endl count characters read endl return 0 include using namespace std int main cout...

scanf 的輸入格式與 EOF 如何結束迴圈

參考 1,scanf d n 以回車作為輸出的結束標誌。返回值為 eof,可以按下下述按鈕結束迴圈,ctrl z 回車 ctrl z 回車 ctrl z 回車 2,scanf s s 以空白字元作為輸出的結束標誌,該空白字元會被丟棄,但要回車才能進入迴圈體內。返回值為 eof,可以按下下述按鈕結束迴...

C primer 第十七章 輸入 輸出和檔案

一,c 輸入和輸出的概述 1 流和緩衝區 流是程式和源流或流目標之間的橋梁 磁碟驅動器以512位元組 或更多 的塊為單位傳輸資訊,程式通常每次只能處理乙個位元組資訊。所以緩衝區用來匹配這兩種不同的資訊傳輸速率。輸出時,先填滿緩衝區,然後把整塊資料傳輸給硬碟,並清空緩衝區,以備下一批輸出使用。2 is...