1. 程式人生 > >C語言檔案操作之fgets()

C語言檔案操作之fgets()

C語言檔案操作之fgets()

原創  2013年01月25日 11:57:00

    來說一說fgets(..)函式。

    原型  char *  fgets(char * s, int n,FILE *stream);

    引數:

         s: 字元型指標,指向儲存讀入資料的緩衝區的地址。

         n: 從流中讀入n-1個字元

         stream : 指向讀取的流。

   返回值:

          1. 當n<=0 時返回NULL,即空指標。

          2. 當n=1 時,返回空串"".

          3. 如果讀入成功,則返回緩衝區的地址。

          4. 如果讀入錯誤或遇到檔案結尾(EOF),則返回NULL.

          看看這個函式的官方說明:

                       /*** 
                    *char *fgets(string, count, stream) - input string from a stream 
                    * 
                    *Purpose:  
                    * get a string, up to count-1 chars or '\n', whichever comes first, 
                    * append '\0' and put the whole thing into string. the '\n' IS included 
                    * in the string. if count<=1 no input is requested. if EOF is found 
                    * immediately, return NULL. if EOF found after chars read, let EOF 
                    * finish the string as '\n' would. 
                    * 
                    *Entry: 
                    * char *string - pointer to place to store string 
                    * int count - max characters to place at string (include \0) 
                    * FILE *stream - stream to read from 
                    * 
                    *Exit: 
                    * returns string with text read from file in it. 
                    * if count <= 0 return NULL 
                    * if count == 1 put null string in string 
                    * returns NULL if error or end-of-file found immediately 
                    * 
                    *Exceptions: 
                    * 
                    *******************************************************************************/ 

            標準庫中fgets(...)的實現:

            

[cpp]  view plain  copy
  1. /****************************************************  
  2.  char *fgets(char *s, int n,  FILE *stream)  
  3.    {  
  4.      register int c;  
  5.      register char *cs;  
  6.      cs=s;  
  7.      while(--n>0 &&(c = getc(stream))!=EOF)  
  8.      if ((*cs++=  c) =='\n')  
  9.            break;  
  10.      *cs ='\0';  
  11.      return (c == EOF && cs == s) ?NULL :s ;  
  12.     }  
  13.   
  14. /********************************************************  



       在用fgets(..)讀入資料時,先定義一個字元陣列或字元指標,如果定義了字元指標 ,那麼一定要初始化。

        example:

              char s[100]; //可以。

              char *s;  //不可以,因為只是聲明瞭一個指標。但並沒有為它分配記憶體緩衝區。

        所以,如果要用指標,則  char *s=(char *)malloc(100*sizeof(char)); 為其分配記憶體空間,c++中用char *s=new char [100];      如果為分配記憶體空間,編譯時不會檢查出問題,但執行時會出現未知錯誤。。

        fgets(...)讀入文字行時的兩種情況。

          1.如果n大於一行的字串長度,那麼當讀到字串末尾的換行符時,fgets(..)會返回。並且在s的最後插入字串結束標誌'\0'。 而s緩衝區剩餘的位置不會再填充。

           example:

              123abc

              fgets(s,10,fp);

              此時,讀入七個字元,123abc\n,實際上還有最後的'\0',所以,strlen(s)=7; 如果要去除末尾的\n,s[strlen(s)-1]='\0';便可。

          2.如果n小於等於一行的字串的長度,那麼讀入n-1個字元,此時並沒有讀入\n因為並沒有到行尾 ,同樣在最後會插入'\0'.

          example:

            123abc

            char  s[5];

            fgets(s,5,fp);

            這時讀入4個字元,123a,並沒有換行符,所以strlen(s)=4.

       fgets(...)讀入整個檔案內容

          通常用while()迴圈來使fges()讀入文字全部內容,並按行讀入。

          

[cpp]  view plain  copy
  1. char s[1024];  
  2.            while((fgets(s,1024,fp))!=NULL)  
  3.             {  
  4.                   printf(s);  
  5.             }  

         當然如果n小於每行的字元個數,也可以讀,只不過讀的次數要多。

          假設一行為 : 123456789

          

[cpp]  view plain  copy
  1. char s[2];  
  2.           int  num=0;  
  3.           while((fgets(s,2,fp))!=NULL)  
  4.             {  
  5.                  printf(s);  
  6.                  n++;  
  7.             }  

          每次讀入一個字元, 最後也會讀完一行,num=10,讀了十次,所以,fgets若沒遇到換行符,會接著從前一次的位置繼續讀入n-1個字元,只要是文字流沒關閉。

         讀入空行的情況:

            第一行   abcdef123

            第二行                       

            第三行  helloworld

            其中第二行為空,fget(..)會把第二行也讀入,因為並未到檔案結尾。

            有時我們並不需要空行,可以這樣做。

          

[cpp]  view plain  copy
  1. while((fgets(s,n,fp))!=NULL)  
  2.              {  
  3.                   if(strlen(s)!=1)    //注意這兒是1不是0,因為儘管是空行,它也會讀入換行符,strlen(s)=1;  
  4.                       printf(s);  
  5.              }  

         fgets(...)從標準裝置讀資料。

            用fgets(...)還也讀入標準輸入裝置(一般為鍵盤)的資訊

            原型  :  fgets(s,n,stdin);

            假設在控制檯下,我們可以用fgets(...)替代gets(),讀入鍵盤輸入的資訊,fgets()是安全的,因為不會像gets()有溢位的可能。。

            比如 :輸入 abc

            fgets(s,n,stdin)也會讀入n-1個字元。但是隻是從stdin流讀入。。。

            

    來說一說fgets(..)函式。

    原型  char *  fgets(char * s, int n,FILE *stream);

    引數:

         s: 字元型指標,指向儲存讀入資料的緩衝區的地址。

         n: 從流中讀入n-1個字元

         stream : 指向讀取的流。

   返回值:

          1. 當n<=0 時返回NULL,即空指標。

          2. 當n=1 時,返回空串"".

          3. 如果讀入成功,則返回緩衝區的地址。

          4. 如果讀入錯誤或遇到檔案結尾(EOF),則返回NULL.

          看看這個函式的官方說明:

                       /*** 
                    *char *fgets(string, count, stream) - input string from a stream 
                    * 
                    *Purpose:  
                    * get a string, up to count-1 chars or '\n', whichever comes first, 
                    * append '\0' and put the whole thing into string. the '\n' IS included 
                    * in the string. if count<=1 no input is requested. if EOF is found 
                    * immediately, return NULL. if EOF found after chars read, let EOF 
                    * finish the string as '\n' would. 
                    * 
                    *Entry: 
                    * char *string - pointer to place to store string 
                    * int count - max characters to place at string (include \0) 
                    * FILE *stream - stream to read from 
                    * 
                    *Exit: 
                    * returns string with text read from file in it. 
                    * if count <= 0 return NULL 
                    * if count == 1 put null string in string 
                    * returns NULL if error or end-of-file found immediately 
                    * 
                    *Exceptions: 
                    * 
                    *******************************************************************************/ 

            標準庫中fgets(...)的實現:

            

[cpp]  view plain  copy
  1. /****************************************************  
  2.  char *fgets(char *s, int n,  FILE *stream)  
  3.    {  
  4.      register int c;  
  5.      register char *cs;  
  6.      cs=s;  
  7.      while(--n>0 &&(c = getc(stream))!=EOF)  
  8.      if ((*cs++=  c) =='\n')  
  9.            break;  
  10.      *cs ='\0';  
  11.      return (c == EOF && cs == s) ?NULL :s ;  
  12.     }  
  13.   
  14. /********************************************************  



       在用fgets(..)讀入資料時,先定義一個字元陣列或字元指標,如果定義了字元指標 ,那麼一定要初始化。

        example:

              char s[100]; //可以。

              char *s;  //不可以,因為只是聲明瞭一個指標。但並沒有為它分配記憶體緩衝區。

        所以,如果要用指標,則  char *s=(char *)malloc(100*sizeof(char)); 為其分配記憶體空間,c++中用char *s=new char [100];      如果為分配記憶體空間,編譯時不會檢查出問題,但執行時會出現未知錯誤。。

        fgets(...)讀入文字行時的兩種情況。

          1.如果n大於一行的字串長度,那麼當讀到字串末尾的換行符時,fgets(..)會返回。並且在s的最後插入字串結束標誌'\0'。 而s緩衝區剩餘的位置不會再填充。

           example:

              123abc

              fgets(s,10,fp);

              此時,讀入七個字元,123abc\n,實際上還有最後的'\0',所以,strlen(s)=7; 如果要去除末尾的\n,s[strlen(s)-1]='\0';便可。

          2.如果n小於等於一行的字串的長度,那麼讀入n-1個字元,此時並沒有讀入\n因為並沒有到行尾 ,同樣在最後會插入'\0'.

          example:

            123abc

            char  s[5];

            fgets(s,5,fp);

            這時讀入4個字元,123a,並沒有換行符,所以strlen(s)=4.

       fgets(...)讀入整個檔案內容

          通常用while()迴圈來使fges()讀入文字全部內容,並按行讀入。

          

[cpp]  view plain  copy
  1. char s[1024];  
  2.            while((fgets(s,1024,fp))!=NULL)  
  3.             {  
  4.                   printf(s);  
  5.             }  

         當然如果n小於每行的字元個數,也可以讀,只不過讀的次數要多。

          假設一行為 : 123456789

          

[cpp]  view plain  copy
  1. char s[2];  
  2.           int  num=0;  
  3.           while((fgets(s,2,fp))!=NULL)  
  4.             {  
  5.                  printf(s);  
  6.                  n++;  
  7.             }  

          每次讀入一個字元, 最後也會讀完一行,num=10,讀了十次,所以,fgets若沒遇到換行符,會接著從前一次的位置繼續讀入n-1個字元,只要是文字流沒關閉。

         讀入空行的情況:

            第一行   abcdef123

            第二行                       

            第三行  helloworld

            其中第二行為空,fget(..)會把第二行也讀入,因為並未到檔案結尾。

            有時我們並不需要空行,可以這樣做。

          

[cpp]  view plain  copy
  1. while((fgets(s,n,fp))!=NULL)  
  2.              {  
  3.                   if(strlen(s)!=1)    //注意這兒是1不是0,因為儘管是空行,它也會讀入換行符,strlen(s)=1;  
  4.                       printf(s);  
  5.              }  

         fgets(...)從標準裝置讀資料。

            用fgets(...)還也讀入標準輸入裝置(一般為鍵盤)的資訊

            原型  :  fgets(s,n,stdin);

            假設在控制檯下,我們可以用fgets(...)替代gets(),讀入鍵盤輸入的資訊,fgets()是安全的,因為不會像gets()有溢位的可能。。

            比如 :輸入 abc

            fgets(s,n,stdin)也會讀入n-1個字元。但是隻是從stdin流讀入。。。