C語言文件操作函數大全


   表頭文件 #include<stdio.h>

   定義函數 void clearerr(FILE * stream);

   函數說明 clearerr()清除參數stream指定的文件流所使用的錯誤旗標。

   返回值

   fclose(關閉文件)

   相關函數 close,fflush,fopen,setbuf

   表頭文件 #include<stdio.h>

   定義函數 int fclose(FILE * stream);

   函數說明 fclose()用來關閉先前fopen()打開的文件。此動作會讓緩衝區內的數據寫入文件中,並釋放系統所提供的文件資源。

   返回值 若關文件動作成功則返回0,有錯誤發生時則返回EOF並把錯誤代碼存到errno。

   錯誤代碼 EBADF表示參數stream非已打開的文件。

   範例 請參考fopen()。

   fdopen(將文件描述詞轉爲文件指針)

   相關函數 fopen,open,fclose

   表頭文件 #include<stdio.h>

   定義函數 FILE * fdopen(int fildes,const char * mode);

   函數說明 fdopen()會將參數fildes 的文件描述詞,轉換爲對應的文件指針後返回。參數mode 字符串則代表着文件指針的流形態,此形態必須和原先文件描述詞讀寫模式相同。關於mode 字符串格式請參考fopen()。

   返回值 轉換成功時返回指向該流的文件指針。失敗則返回NULL,並把錯誤代碼存在errno中。

   範例

   #include<stdio.h>

    main()

    {

    FILE * fp =fdopen(0,”w+”);

    fprintf(fp,”%s\n”,”hello!”);

    fclose(fp);

    }

   執行 hello!

   feof(檢查文件流是否讀到了文件尾)

   相關函數 fopen,fgetc,fgets,fread

   表頭文件 #include<stdio.h>

   定義函數 int feof(FILE * stream);

   函數說明 feof()用來偵測是否讀取到了文件尾,尾數stream爲fopen()所返回之文件指針。如果已到文件尾則返回非零值,其他情況返回0。

   返回值 返回非零值代表已到達文件尾。

   fflush(更新緩衝區)

   相關函數 write,fopen,fclose,setbuf

   表頭文件 #include<stdio.h>

   定義函數 int fflush(FILE* stream);

   函數說明 fflush()會強迫將緩衝區內的數據寫回參數stream指定的文件中。如果參數stream爲NULL,fflush()會將所有打開的文件數據更新。

   返回值 成功返回0,失敗返回EOF,錯誤代碼存於errno中。

   錯誤代碼 EBADF 參數stream 指定的文件未被打開,或打開狀態爲只讀。其它錯誤代碼參考write()。

  fgetc(由文件中讀取一個字符)

   相關函數 open,fread,fscanf,getc

   表頭文件 include<stdio.h>

   定義函數 nt fgetc(FILE * stream);

   函數說明 fgetc()從參數stream所指的文件中讀取一個字符。若讀到文件尾而無數據時便返回EOF。

   返回值 getc()會返回讀取到的字符,若返回EOF則表示到了文件尾。

   範例

   #include<stdio.h>

    main()

    {

    FILE *fp;

    int c;

    fp=fopen(“exist”,”r”);

    while((c=fgetc(fp))!=EOF)

    printf(“%c”,c);

    fclose(fp);

    }

   fgets(由文件中讀取一字符串)

   相關函數 open,fread,fscanf,getc

   表頭文件 include<stdio.h>

   定義函數 har * fgets(char * s,int size,FILE * stream);

   函數說明 fgets()用來從參數stream所指的文件內讀入字符並存到參數s所指的內存空間,直到出現換行字符、讀到文件尾或是已讀了size-1個字符爲止,最後會加上NULL作爲字符串結束。

   返回值 gets()若成功則返回s指針,返回NULL則表示有錯誤發生。

   範例

   #include<stdio.h>

    main()

    {

    char s[80];

    fputs(fgets(s,80,stdin),stdout);

    }

   執行 this is a test /*輸入*/

   this is a test /*輸出*/

   fileno(返回文件流所使用的文件描述詞)

   相關函數 open,fopen

   表頭文件 #include<stdio.h>

   定義函數 int fileno(FILE * stream);

   函數說明 fileno()用來取得參數stream指定的文件流所使用的文件描述詞。

   返回值 返回文件描述詞。

   範例

   #include<stdio.h>

    main()

    {

    FILE * fp;

    int fd;

    fp=fopen(“/etc/passwd”,”r”);

    fd=fileno(fp);

    printf(“fd=%d\n”,fd);

    fclose(fp);

    }

   執行 fd=3

   fopen(打開文件)

   相關函數 open,fclose

   表頭文件 #include<stdio.h>

   定義函數 FILE * fopen(const char * path,const char * mode);

 

函數說明 參數path字符串包含欲打開的文件路徑及文件名,參數mode字符串則代表着流形態。

   mode有下列幾種形態字符串:

   r 打開只讀文件,該文件必須存在。

   r+ 打開可讀寫的文件,該文件必須存在。

   w 打開只寫文件,若文件存在則文件長度清爲0,即該文件內容會消失。若文件不存在則建立該文件。

   w+ 打開可讀寫文件,若文件存在則文件長度清爲零,即該文件內容會消失。若文件不存在則建立該文件。

   a 以附加的方式打開只寫文件。若文件不存在,則會建立該文件,如果文件存在,寫入的數據會被加到文件尾,即文件原先的內容會被保留。

   a+ 以附加方式打開可讀寫的文件。若文件不存在,則會建立該文件,如果文件存在,寫入的數據會被加到文件尾後,即文件原先的內容會被保留。

   上述的形態字符串都可以再加一個b字符,如rb、w+b或ab+等組合,加入b 字符用來告訴函數庫打開的文件爲二進制文件,而非純文字文件。不過在POSIX系統,包含Linux都會忽略該字符。由fopen()所建立的新文件會具有S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH(0666)權限,此文件權限也會參考umask值。

   返回值 文件順利打開後,指向該流的文件指針就會被返回。若果文件打開失敗則返回NULL,並把錯誤代碼存在errno 中。

   附加說明 一般而言,開文件後會作一些文件讀取或寫入的動作,若開文件失敗,接下來的讀寫動作也無法順利進行,所以在fopen()後請作錯誤判斷及處理。

   範例

   #include<stdio.h>

    main()

    {

    FILE * fp;

    fp=fopen(“noexist”,”a+”);

    if(fp= =NULL) return;

    fclose(fp);

    }

   fputc(將一指定字符寫入文件流中)

   相關函數 fopen,fwrite,fscanf,putc

   表頭文件 #include<stdio.h>

   定義函數 int fputc(int c,FILE * stream);

   函數說明 fputc 會將參數c 轉爲unsigned char 後寫入參數stream 指定的文件中。

   返回值 fputc()會返回寫入成功的字符,即參數c。若返回EOF則代表寫入失敗。

   範例

   #include<stdio.h>

    main()

    {

    FILE * fp;

    char a[26]=”abcdefghijklmnopqrstuvwxyz”;

    int i;

    fp= fopen(“noexist”,”w”);

    for(i=0;i<26;i++)

    fputc(a,fp);

    fclose(fp);

    }

   fputs(將一指定的字符串寫入文件內)

   相關函數 fopen,fwrite,fscanf,fputc,putc

   表頭文件 #include<stdio.h>

   定義函數 int fputs(const char * s,FILE * stream);

   函數說明 fputs()用來將參數s所指的字符串寫入到參數stream所指的文件內。

   返回值 若成功則返回寫出的字符個數,返回EOF則表示有錯誤發生。

   範例 請參考fgets()。

   fread(從文件流讀取數據)

   相關函數 fopen,fwrite,fseek,fscanf

   表頭文件 #include<stdio.h>

   定義函數 size_t fread(void * ptr,size_t size,size_t nmemb,FILE * stream);

   函數說明 fread()用來從文件流中讀取數據。參數stream爲已打開的文件指針,參數ptr 指向欲存放讀取進來的數據空間,讀取的字符數以參數size*nmemb來決定。Fread()會返回實際讀取到的nmemb數目,如果此值比參數nmemb 來得小,則代表可能讀到了文件尾或有錯誤發生,這時必須用feof()或ferror()來決定發生什麼情況。

   返回值 返回實際讀取到的nmemb數目。

   附加說明

   範例

   #include<stdio.h>

    #define nmemb 3

    struct test

    {

    char name[20];

    int size;

    }s[nmemb];

    int main(){

    FILE * stream;

    int i;

    stream = fopen(“/tmp/fwrite”,”r”);

    fread(s,sizeof(struct test),nmemb,stream);

    fclose(stream);

    for(i=0;i<nmemb;i++)

    printf(“name[%d]=%-20s:size[%d]=%d\n”,i,s.name,i,s.size);

    }

   執行

   name[0]=Linux! size[0]=6

   name[1]=FreeBSD! size[1]=8

   name[2]=Windows2000 size[2]=11

   freopen(打開文件)

   相關函數 fopen,fclose

   表頭文件 #include<stdio.h>

   定義函數 FILE * freopen(const char * pathconst char * mode,FILE * stream);

   函數說明 參數path字符串包含欲打開的文件路徑及文件名,參數mode請參考fopen()說明。參數stream爲已打開的文件指針。Freopen()會將原stream所打開的文件流關閉,然後打開參數path的文件。

#include<stdio.h>

    main()

    {

    FILE * fp;

    fp=fopen(“/etc/passwd”,”r”);

    fp=freopen(“/etc/group”,”r”,fp);

    fclose(fp);

    }

   fseek(移動文件流的讀寫位置)

   相關函數 rewind,ftell,fgetpos,fsetpos,lseek

   表頭文件 #include<stdio.h>

   定義函數 int fseek(FILE * stream,long offset,int whence);

   函數說明 fseek()用來移動文件流的讀寫位置。參數stream爲已打開的文件指針,參數offset爲根據參數whence來移動讀寫位置的位移數。

   參數 whence爲下列其中一種:

   SEEK_SET從距文件開頭offset位移量爲新的讀寫位置。SEEK_CUR 以目前的讀寫位置往後增加offset個位移量。

   SEEK_END將讀寫位置指向文件尾後再增加offset個位移量。

   當whence值爲SEEK_CUR 或SEEK_END時,參數offset允許負值的出現。

   下列是較特別的使用方式:

   1) 欲將讀寫位置移動到文件開頭時:fseek(FILE *stream,0,SEEK_SET);

   2) 欲將讀寫位置移動到文件尾時:fseek(FILE *stream,0,0SEEK_END);

   返回值 當調用成功時則返回0,若有錯誤則返回-1,errno會存放錯誤代碼。

   附加說明 fseek()不像lseek()會返回讀寫位置,因此必須使用ftell()來取得目前讀寫的位置。

   範例

   #include<stdio.h>

    main()

    {

    FILE * stream;

    long offset;

    fpos_t pos;

    stream=fopen(“/etc/passwd”,”r”);

    fseek(stream,5,SEEK_SET);

    printf(“offset=%d\n”,ftell(stream));

    rewind(stream);

    fgetpos(stream,&pos);

    printf(“offset=%d\n”,pos);

    pos=10;

    fsetpos(stream,&pos);

    printf(“offset = %d\n”,ftell(stream));

    fclose(stream);

    }

   執行 offset = 5

   offset =0

   offset=10

   ftell(取得文件流的讀取位置)

   相關函數 fseek,rewind,fgetpos,fsetpos

   表頭文件 #include<stdio.h>

   定義函數 long ftell(FILE * stream);

   函數說明 ftell()用來取得文件流目前的讀寫位置。參數stream爲已打開的文件指針。

   返回值 當調用成功時則返回目前的讀寫位置,若有錯誤則返回-1,errno會存放錯誤代碼。

   錯誤代碼 EBADF 參數stream無效或可移動讀寫位置的文件流。

   範例 參考fseek()。

   fwrite(將數據寫至文件流)

   相關函數 fopen,fread,fseek,fscanf

   表頭文件 #include<stdio.h>

   定義函數 size_t fwrite(const void * ptr,size_t size,size_t nmemb,FILE * stream);

   函數說明 fwrite()用來將數據寫入文件流中。參數stream爲已打開的文件指針,參數ptr 指向欲寫入的數據地址,總共寫入的字符數以參數size*nmemb來決定。Fwrite()會返回實際寫入的nmemb數目。

   返回值 返回實際寫入的nmemb數目。

   範例

   #include<stdio.h>

    #define set_s (x,y) {strcoy(s[x].name,y);s[x].size=strlen(y);}

    #define nmemb 3

    struct test

    {

    char name[20];

    int size;

    }s[nmemb];

    main()

    {

    FILE * stream;

    set_s(0,”Linux!”);

    set_s(1,”FreeBSD!”);

    set_s(2,”Windows2000.”);

    stream=fopen(“/tmp/fwrite”,”w”);

    fwrite(s,sizeof(struct test),nmemb,stream);

    fclose(stream);

    }

   執行 參考fread()。

   getc(由文件中讀取一個字符)

   相關函數 read,fopen,fread,fgetc

   表頭文件 #include<stdio.h>

   定義函數 int getc(FILE * stream);

   函數說明 getc()用來從參數stream所指的文件中讀取一個字符。若讀到文件尾而無數據時便返回EOF。雖然getc()與fgetc()作用相同,但getc()爲宏定義,非真正的函數調用。

   返回值 getc()會返回讀取到的字符,若返回EOF則表示到了文件尾。

   範例 參考fgetc()。

   getchar(由標準輸入設備內讀進一字符)

   相關函數 fopen,fread,fscanf,getc

   表頭文件 #include<stdio.h>

   定義函數 int getchar(void);

   函數說明 getchar()用來從標準輸入設備中讀取一個字符。然後將該字符從unsigned char轉換成int後返回。

   返回值 getchar()會返回讀取到的字符,若返回EOF則表示有錯誤發生。

   附加說明 getchar()非真正函數,而是getc(stdin)宏定義。

  範例

   #include<stdio.h>

    main()

    {

    FILE * fp;

    int c,i;

    for(i=0li<5;i++)

    {

    c=getchar();

    putchar(c);

    }

    }

   執行 1234 /*輸入*/

   1234 /*輸出*/

   gets(由標準輸入設備內讀進一字符串)

   相關函數 fopen,fread,fscanf,fgets

   表頭文件 #include<stdio.h>

   定義函數 char * gets(char *s);

   函數說明 gets()用來從標準設備讀入字符並存到參數s所指的內存空間,直到出現換行字符或讀到文件尾爲止,最後加上NULL作爲字符串結束。

   返回值 gets()若成功則返回s指針,返回NULL則表示有錯誤發生。

   附加說明 由於gets()無法知道字符串s的大小,必須遇到換行字符或文件尾纔會結束輸入,因此容易造成緩衝溢出的安全性問題。建議使用fgets()取代。

   範例 參考fgets()

    mktemp(產生唯一的臨時文件名)

   相關函數 tmpfile

   表頭文件 #include<stdlib.h>

   定義函數 char * mktemp(char * template);

   函數說明 mktemp()用來產生唯一的臨時文件名。參數template所指的文件名稱字符串中最後六個字符必須是XXXXXX。產生後的文件名會借字符串指針返回。

   返回值 文件順利打開後,指向該流的文件指針就會被返回。如果文件打開失敗則返回NULL,並把錯誤代碼存在errno中。

   附加說明 參數template所指的文件名稱字符串必須聲明爲數組,如:

   char template[ ]=”template-XXXXXX”;

   不可用char * template=”template-XXXXXX”;

   範例

   #include<stdlib.h>

    main()

    {

    char template[ ]=”template-XXXXXX”;

    mktemp(template);

    printf(“template=%s\n”,template);

    }

   putc(將一指定字符寫入文件中)

   相關函數 fopen,fwrite,fscanf,fputc

   表頭文件 #include<stdio.h>

   定義函數 int putc(int c,FILE * stream);

   函數說明 putc()會將參數c轉爲unsigned char後寫入參數stream指定的文件中。雖然putc()與fputc()作用相同,但putc()爲宏定義,非真正的函數調用。

   返回值 putc()會返回寫入成功的字符,即參數c。若返回EOF則代表寫入失敗。

   範例 參考fputc()。

   putchar(將指定的字符寫到標準輸出設備)

   相關函數 fopen,fwrite,fscanf,fputc

   表頭文件 #include<stdio.h>

   定義函數 int putchar (int c);

   函數說明 putchar()用來將參數c字符寫到標準輸出設備。

   返回值 putchar()會返回輸出成功的字符,即參數c。若返回EOF則代表輸出失敗。

   附加說明 putchar()非真正函數,而是putc(c,stdout)宏定義。

   範例 參考getchar()。

   rewind(重設文件流的讀寫位置爲文件開頭)

   相關函數 fseek,ftell,fgetpos,fsetpos

   表頭文件 #include<stdio.h>

   定義函數 void rewind(FILE * stream);

   函數說明 rewind()用來把文件流的讀寫位置移至文件開頭。參數stream爲已打開的文件指針。此函數相當於調用fseek(stream,0,SEEK_SET)。

   返回值

   範例 參考fseek()

   setbuf(設置文件流的緩衝區)

   相關函數 setbuffer,setlinebuf,setvbuf

   表頭文件 #include<stdio.h>

   定義函數 void setbuf(FILE * stream,char * buf);

   函數說明 在打開文件流後,讀取內容之前,調用setbuf()可以用來設置文件流的緩衝區。參數stream爲指定的文件流,參數buf指向自定的緩衝區起始地址。如果參數buf爲NULL指針,則爲無緩衝IO。Setbuf()相當於調用:setvbuf(stream,buf,buf?_IOFBF:_IONBF,BUFSIZ)

   返回值

   setbuffer(設置文件流的緩衝區)

   相關函數 setlinebuf,setbuf,setvbuf

   表頭文件 #include<stdio.h>

   定義函數 void setbuffer(FILE * stream,char * buf,size_t size);

   函數說明 在打開文件流後,讀取內容之前,調用setbuffer()可用來設置文件流的緩衝區。

   參數stream爲指定的文件流,參數buf指向自定的緩衝區起始地址,參數size爲緩衝區大小。

   返回值

   setlinebuf(設置文件流爲線性緩衝區)

   相關函數 setbuffer,setbuf,setvbuf

   表頭文件 #include<stdio.h>

   定義函數 void setlinebuf(FILE * stream);

   函數說明 setlinebuf()用來設置文件流以換行爲依據的無緩衝IO。相當於調用:setvbuf(stream,(char * )NULL,_IOLBF,0);請參考setvbuf()。

   返回值

   setvbuf(設置文件流的緩衝區)

   相關函數 setbuffer,setlinebuf,setbuf

表頭文件 #include<stdio.h>

   定義函數 int setvbuf(FILE * stream,char * buf,int mode,size_t size);

   函數說明 在打開文件流後,讀取內容之前,調用setvbuf()可以用來設置文件流的緩衝區。參數stream爲指定的文件流,參數buf指向自定的緩衝區起始地址,參數size爲緩衝區大小,參數mode有下列幾種

   _IONBF 無緩衝IO

   _IOLBF 以換行爲依據的無緩衝IO

   _IOFBF 完全無緩衝IO。如果參數buf爲NULL指針,則爲無緩衝IO。

   返回值

   ungetc(將指定字符寫回文件流中)

   相關函數 fputc,getchar,getc

   表頭文件 #include<stdio.h>

   定義函數 int ungetc(int c,FILE * stream);

   函數說明 ungetc()將參數c字符寫回參數stream所指定的文件流。這個寫回的字符會由下一個讀取文件流的函數取得。

   返回值 成功則返回c 字符,若有錯誤則返回EOF。

 

abcdefg

一、標準文件的讀寫

      1.文件的打開fopen()

          文件的打開操作表示將給用戶指定的文件在內存分配一個FILE結構區,並將該結構的指針返回給用戶程序,以後用戶程序就可用此FILE指針來實現對指定文件的存取操作了。當使用打開函數時,必須給出文件名、文件操作方式(讀、寫或讀寫),如果該文件名不存在,就意味着建立(只對寫文件而言,對讀文件則出錯),並將文件指針指向文件開頭。若已有一個同名文件存在,則刪除該文件,若無同名文件,則建立該文件,並將文件指針指向文件開頭。

              fopen(char *filename,char *type);

          其中*filename是要打開文件的文件名指針,一般用雙引號括起來的文件名錶示,也可使用雙反斜槓隔開的路徑名。而*type參數表示了對打開文件的操作方式。其可採用的操作方式如下:

 

              方式                      含義

               "r"             打開,只讀

               "w"             打開,文件指針指到頭,只寫

               "a"             打開,指向文件尾,在已存在文件中追加

               "rb"            打開一個二進制文件,只讀

               "wb"            打開一個二進制文件,只寫

               "ab"            打開一個二進制文件,進行追加

               "r+"            以讀/寫方式打開一個已存在的文件

               "w+"            以讀/寫方式建立一個新的文本文件

               "a+"            以讀/寫方式打開一個文件文件進行追加

               "rb+"           以讀/寫方式打開一個二進制文件

               "wb+"           以讀/寫方式建立一個新的二進制文件

       "rt+"    讀寫打開一個文本文件,允許讀和寫

              “wt+”    讀寫打開或建立一個文本文件,允許讀寫

               "ab+"           以讀/寫方式打開一個二進制文件進行追加

 

          當用fopen(0成功的打開一個文件時,該函數將返回一個FILE指針,如果文件打開失敗,將返回一個NULL指針。如想打開test文件,進行寫:

 

              FILE *fp;

              if((fp=fopen("test","w"))==NULL)

              {

                  printf("File cannot be    opened\n");

                  exit();

              }

              else

                  printf("File opened for writing\n");

                    ……

              fclose(fp);

 

          DOS操作系統對同時打開的文件數目是有限制的,缺省值爲5,可以通過修改CONFIG.SYS文件改變這個設置。

 

      2.關閉文件函數fclose()

          文件操作完成後,必須要用fclose()函數進行關閉,這是因爲對打開的文件進行寫入時,若文件緩衝區的空間未被寫入的內容填滿,這些內容不會寫到打開的文件中去而丟失。只有對打開的文件進行關閉操作時,停留在文件緩衝區的內容才能寫到該文件中去,從而使文件完整。再者一旦關閉了文件,該文件對應的FILE結構將被釋放,從而使關閉的文件得到保護,因爲這時對該文件的存取操作將不會進行。文件的關閉也意味着釋放了該文件的緩衝區。

              int fclose(FILE *stream);

          它表示該函數將關閉FILE指針對應的文件,並返回一個整數值。若成功地關閉了文件,則返回一個0值,否則返回一個非0值。常用以下方法進行測試:

 

              if(fclose(fp)!=0)

              {

                  printf("File cannot be closed\n");

                  exit(1);

              }

              else

                  printf("File is now closed\n");

 

          當打開多個文件進行操作,而又要同時關閉時,可採用fcloseall()函數,它將關閉所有在程序中打開的文件。

              int fcloseall();

          該函數將關閉所有已打開的文件,將各文件緩衝區未裝滿的內容寫到相應的文件中去,接着釋放這些緩衝區,並返回關閉文件的數目。如關閉了4個文件,則當執行:

              n=fcloseall();

          時,n應爲4。

      3.文件的讀寫

          (1).讀寫文件中字符的函數(一次只讀寫文件中的一個字符):

 

              int fgetc(FILE *stream);

              int fgetchar(void);

              int fputc(int ch,FILE *stream);

              int fputchar(int ch);

              int getc(FILE *stream);

              int putc(int ch,FILE *stream);

          其中fgetc()函數將把由流指針指向的文件中的一個字符讀出,例如:

              ch=fgetc(fp);

          將把流指針fp指向的文件中的一個字符讀出,並賦給ch,當執行fgetc()函數時,若當時文件指針指到文件尾,即遇到文件結束標誌EOF(其對應值爲-1),該函數返回一個-1給ch,在程序中常用檢查該函數返回值是否爲-1來判斷是否已讀到文件尾,從而決定是否繼續。

 

              #include "stdio.h"

              main()

              {

                  FILE *fp;

                  ch ch;

                  if((fp=fopen("myfile.tex","r"))==NULL)

                  {

                      printf("file cannot be opened\n");

                      exit(1);

                  }

                  while((ch=fgetc(fp))!=EOF) fputc(ch,stdout);

                  fclose(fp);

              }

               

          該程序以只讀方式打開myfile.txt文件,在執行while循環時,文件指針每循環一次後移一個字符位置。用fgetc()函數將文件指針指定的字符讀到ch變量中,然後用fputc()函數在屏幕上顯示,當讀到文件結束標誌EOF時,變關閉該文件。

          上面的程序用到了fputc()函數,該函數將字符變量ch的值寫到流指針指定的文件中去,由於流指針用的是標準輸出(顯示器)的FILE指針stdout,故讀出的字符將在顯示器上顯示。又比如:

              fputc(ch,fp);

          該函數執行結構,將把ch表示的字符送到流指針fp指向的文件中去。

              在TC中,putc()等價於fput(),getc()等價於fgetc()。

              putchar(c)相當於fputc(c,stdout);getchar()相當於fgetc(stdin)。

          注意,這裏使用char ch,其實是不科學的,因爲最後判斷結束標誌時,是看ch!=EOF,而EOF的值爲-1,這顯然和char是不能比較的。所以,某些使用,我們都定義成int ch。

          (2).讀寫文件中字符串的函數

               

              char *fgets(char *string,int n,FILE *stream);

              char *gets(char *s);

              int fprintf(FILE *stream,char *format,variable-list);

              int fputs(char *string,FILE *stream);

              int fscanf(FILE *stream,char *format,variable-list);

          其中fgets()函數將把由流指針指定的文件中n-1個字符,讀到由指針stream指向的字符數組中去,例如:

              fgets(buffer,9,fp);

          將把fp指向的文件中的8個字符讀到buffer內存區,buffer可以是定義的字符數組,也可以是動態分配的內存區。

          注意,fgets()函數讀到'\n'就停止,而不管是否達到數目要求。同時在讀取字符串的最後加上'\0'。

          fgets()函數執行完以後,返回一個指向該串的指針。如果讀到文件尾或出錯,則均返回一個空指針NULL,所以長用feof()函數來測定是否到了文件尾或者是ferror()函數來測試是否出錯,例如下面的程序用fgets()函數讀test.txt文件中的第一行並顯示出來:

          

              #include "stdio.h"

              main()

              {

                  FILE *fp;

                  char str[128];

                  if((fp=fopen("test.txt","r"))==NULL)

                  {

                      printf("cannot open file\n");

                      exit(1);

                  }

                  while(!feof(fp))

                  {

                      if(fgets(str,128,fp)!=NULL) printf("%s",str);

                  }

                  fclose(fp);

              }

 

          gets()函數執行時,只要未遇到換行符或文件結束標誌,將一直讀下去。因此讀到什麼時候爲止,需要用戶進行控制,否則可能造成存儲區的溢出。

          fputs()函數想指定文件寫入一個由string指向的字符串,'\0'不寫入文件。                

          fprintf()和fscanf()同printf()和scanf()函數類似,不同之處就是printf()函數是想顯示器輸出,fprintf()則是向流指針指向的文件輸出;fscanf()是從文件輸入。

 

          下面程序是向文件test.dat裏輸入一些字符:

 

              #include<stdio.h>

              main()

              {

                  char *s="That's good news";

                  int i=617;

                  FILE *fp;

                  fp=fopne("test.dat", "w");   

                  fputs("Your score of TOEFLis",fp);   

                  fputc(':', fp);                      

                  fprintf(fp, "%d\n", i);              

                  fprintf(fp, "%s", s);                

                  fclose(fp);

              }

              用DOS的TYPE命令顯示TEST.DAT的內容如下所示:

              屏幕顯示

                  Your score of TOEFL is: 617

                  That's good news

               

          下面的程序是把上面的文件test.dat裏的內容在屏幕上顯示出來:

       

              #include<stdio.h>

              main()

              {

                  char *s, m[20];

                  int i;

                  FILE    *fp;

                  fp=fopen("test.dat", "r");    

                  fgets(s, 24, fp);             

                  printf("%s", s);

                  fscanf(fp, "%d", &i);         

                  printf("%d", i);

                  putchar(fgetc(fp));           

                  fgets(m, 17, fp);             

                  puts(m);                      

                  fclose(fp);

                  getch();

              }

              運行後屏幕顯示:

                  Your score of TOEFL is: 617

                  That's good news

 

      4.清除和設置文件緩衝區

          (1).清除文件緩衝區函數:

              int fflush(FILE *stream);

              int flushall();

               

              fflush()函數將清除由stream指向的文件緩衝區裏的內容,常用於寫完一些數據後,立即用該函數清除緩衝區,以免誤操作時,破壞原來的數據。

              flushall()將清除所有打開文件所對應的文件緩衝區。

          (2).設置文件緩衝區函數

              void setbuf(FILE *stream,char *buf);

              void setvbuf(FILE *stream,char *buf,int type,unsigned size);

          這兩個函數將使得打開文件後,用戶可建立自己的文件緩衝區,而不使用fopen()函數打開文件設定的默認緩衝區。               

          對於setbuf()函數,buf指出的緩衝區長度由頭文件stdio.h中定義的宏BUFSIZE的值決定,缺省值爲512字節。當選定buf爲空時,setbuf函數將使的文件I/O不帶緩衝。而對setvbuf函數,則由malloc函數來分配緩衝區。參數size指明瞭緩衝區的長度(必須大於0),而參數type則表示了緩衝的類型,其值可以取如下值:

 

                  type 值             含義

                   _IOFBF        文件全部緩衝,即緩衝區裝滿後,才能對文件讀寫

                   _IOLBF        文件行緩衝,即緩衝區接收到一個換行符時,才能對文件讀寫

                   _IONBF        文件不緩衝,此時忽略buf,size的值,直接讀寫文件,不再經過文件緩衝區緩衝

 

      5.文件的隨機讀寫函數

          前面介紹的文件的字符/字符串讀寫,均是進行文件的順序讀寫,即總是從文件的開頭開始進行讀寫。這顯然不能滿足我們的要求,C語言提供了移動文件指針和隨機讀寫的函數,它們是:

          (1).移動文件指針函數:

              long ftell(FILE *stream);

              int rewind(FILE *stream);

              fseek(FILE *stream,long offset,int origin);

 

              函數ftell()用來得到文件指針離文件開頭的偏移量。當返回值是-1時表示出錯。

              rewind()函數用於文件指針移到文件的開頭,當移動成功時,返回0,否則返回一個非0值。

              fseek()函數用於把文件指針以origin爲起點移動offset個字節,其中origin指出的位置可有以下幾種:

 

                 origin           數值             代表的具體位置

 

                SEEK_SET          0               文件開頭

                SEEK_CUR          1               文件指針當前位置

                SEEK_END          2               文件尾

 

             例如:

                 fseek(fp,10L,0);

             把文件指針從文件開頭移到第10字節處,由於offset參數要求是長整型數,故其數後帶L。

                 fseek(fp,-15L,2);

             把文件指針從文件尾向前移動15字節。

 

         (2).文件隨機讀寫函數

 

             int fread(void *ptr,int size,int nitems,FILE *stream);

             int fwrite(void *ptr,int size,int nitems,FILE *stream);

               

             fread()函數從流指針指定的文件中讀取nitems個數據項,每個數據項的長度爲size個字節,讀取的nitems數據項存入由ptr指針指向的內存緩衝區中,

在執行fread()函數時,文件指針隨着讀取的字節數而向後移動,最後移動結束的位置等於實際讀出的字節數。該函數執行結束後,將返回實際讀出的數據項數,

這個數據項數不一定等於設置的nitems,因爲若文件中沒有足夠的數據項,或讀中間出錯,都會導致返回的數據項數少於設置的nitems。當返回數不等於nitems時

,可以用feof()或ferror()函數進行檢查。

 

             fwrite()函數從ptr指向的緩衝區中取出長度爲size字節的nitems個數據項,寫入到流指針stream指向的文件中,執行該操作後,文件指針將向後移動,

移動的字節數等於寫入文件的字節數目。該函數操作完成後,也將返回寫入的數據項數。

 

 

 

二、非標準文件的讀寫

      這類函數最早用於UNIX操作系統,ANSI標準未定義,但有時也經常用到,DOS 3.0以上版本支持這些函數。它們的頭文件爲io.h。

      由於我們不常用這些函數,所以在這裏就簡單說一下。

      1.文件的打開和關閉

          open()函數的作用是打開文件,其調用格式爲:

              int open(char *filename, int access);

          該函數表示按access的要求打開名爲filename的文件,返回值爲文件描述字,其中access有兩部分內容:

          基本模式和修飾符, 兩者用" "("或")方式連接。修飾符可以有多個, 但基本模式只能有一個。

 

                           access的規定

              --------------------------------------------------------

              基本模式      含義      修飾符           含    義

              --------------------------------------------------------

              O_RDONLY      只讀     O_APPEND     文件指針指向末尾

              O_WRONLY      只寫     O_CREAT      文件不存在時創建文件, 屬性按基本模式屬性

              O_RDWR        讀寫     O_TRUNC      若文件存在, 將其長度縮爲0, 屬性不變

                                 O_BINARY     打開一個二進制文件

                                 O_TEXT       打開一個文字文件

              ---------------------------------------------------------

              open()函數打開成功, 返回值就是文件描述字的值(非負值), 否則返回-1。

              close()函數的作用是關閉由open()函數打開的文件, 其調用格式爲:

                  int close(int handle);

              該函數關閉文件描述字handle相連的文件。

 

      2.讀寫函數

          int read(int handle, void *buf, int count);

          read()函數從handle(文件描述字)相連的文件中, 讀取count個字節放到buf所指的緩衝區中,

      返回值爲實際所讀字節數, 返回-1表示出錯。返回0 表示文件結束。

 

           write()函數的調用格式爲:

               int write(int handle, void *buf, int count);

           write()函數把count個字節從buf指向的緩衝區寫入與handle相連的文件中, 返回值爲實際寫入的字節數。

             

      3.隨機定位函數

          lseek()函數的調用格式爲:

               int lseek(int handle, long offset, int fromwhere);

          該函數對與handle相連的文件位置指針進行定位,功能和用法與fseek()函數相同。

 

          tell()函數的調用格式爲:

               long tell(int handle);

          該函數返回與handle相連的文件現生位置指針, 功能和用法與ftell()相同

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章