這是一篇關於getline()函數的博客,以總結對輸入輸出流的掌握,再也不在這些問題上栽跟頭~ios
--------------------------編程
1.首先咱們知道,getline()函數的基本做用,在C++標準庫裏面的函數定義爲:istream& getline ( istream &is , string &str , char delim ); 這裏須要解釋一下,istream &is是輸入流,譬如cin; string &str是將讀取到的字符串存儲的地方(命名自由); char delim表明,讀入遇到該delim時就終止(能夠省略該參數,省略則默認爲'\n',換行符)。 例以下面代碼1:數組
1 #include <iostream> 2 #include <string> 3 using namespace std; 4 5 int main(){ 6 string data; 7 getline(cin,data,'$'); 8 cout<<data; 9 }
結果如圖:緩存
字符'$'後面的'!'並無被讀入,讀入的部分爲It's a apple app
2.另外關於在while循環中遇到getline()函數,那又是怎樣的一種體驗呢? ide
通常咱們會認爲while(getline(cin,str))在遇到空白輸入時候,就會終止。其實否則,當你在不斷的敲Enter鍵想讓其終止時,會發現光標仍是在往下走,並無結束程序的意思。那是由於函數定義,是讀入「輸入流」:Enter鍵的換行也是輸入流。=_=||.....別擔憂,這時候鍵入EOF回車(即window Ctrl+z; Linux Ctrl+d),就能夠完成輸入了。 爲何會這樣呢?由於getline()首先從標準輸入設備上讀入字符,而後返回給輸入流cin(而不是line,line爲空即爲輸入結束),注意是cin,因此while()判斷語句的判斷對象是cin,也就是判斷當前是否存在有效的輸入流。 函數
3.此外gets()函數,也是一個點,須要掌握,前幾天作題的時候小有涉略,這裏也給出總結。這是C語言中的一個函數,一篇博客中寫道:從流中讀取字符串。測試
gets()函數用於從緩衝區中讀取字符串,原型以下: char *gets(char *string); gets()函數從流中讀取字符串,直到出現換行符或文件結尾爲止,最後加上NULL做爲字符串結束。所讀取的字符串暫時存在給定的參數string中。若成功,則返回string的指針,不然返回NULL。(該函數並不能處理string類型, DEV-C++對這一編寫狀況報錯)。優化
另外:因爲gets()不檢查字符串string的大小,只在遇到換行符或者文件結尾的時候纔會結束,這樣就會出現緩存區溢出的現象,致使程序崩潰。這個時候要換函數fgets(). 這個函數,因爲該特色因此並不被看好,多數編程者不推薦該函數。可是在DEV-C++中測試的結果並未如此:spa
1 #include <stdio.h> 2 using namespace std; 3 4 int main(){ 5 char data[5]; 6 gets(data); 7 printf("%s",data); 8 }
結果以下:
這是編譯器優化的結果,編譯器的優化解決了這個程序的bug。
4.下面介紹fgets()函數的狀況。
fgets()函數比gets()函數高明的地方是指出了要讀入字符串的大小。
fgets()函數的原型是 char * fgets(char * string, int size, FILE * stream); string是一個字符數組,用來保存讀取到的字符;size用來記錄字符串的大小,若是字符個數大於size-1,則最後讀取size-1個字符,並在最後一個字符處補'\0';若字符個數小於等於size-1,則可以正常讀取,也就是最多能讀取size-1個字符;FILE * stream表明一個文件指針流。
若是讀取成功,則返回讀取到的字符串,即string;失敗或者讀取到文件尾,則返回NULL。所以咱們不能直接經過fgets()的返回值來判斷函數是不是出錯而終止的,應該藉助feof()函數或者ferror()函數來判斷。(放心,這裏就不拓展了,細節本身百度。) 例以下面代碼3:
1 #include <stdio.h> 2 using namespace std; 3 4 int main(void) 5 { 6 FILE *fp = NULL; 7 char buf[512] = {0}; 8 9 fp = fopen("touch.txt","r"); 10 if ( NULL == fp) { 11 printf("open file failed.\n"); 12 return 0; 13 } 14 15 int i=7; 16 while(i--){ 17 fgets(buf, 5, fp); 18 printf("the 5 char buf = %s\n", buf); 19 } 20 21 return 0; 22 }
其中touch.txt中存儲內容爲:sadhajdshaksjdhajkd
結果以下:
關於fgets()函數讀取文件,size要大於 該行總數+2.(多出來的兩個,一個保存文件自己的'\n'換行,一個保存字符串自己的結束表示'\0' .)。文件並不會繼續讀下去,僅僅只是這一行讀取完,隨後指向文件的指針會自動偏移至下一行。