一区二区三区日韩精品-日韩经典一区二区三区-五月激情综合丁香婷婷-欧美精品中文字幕专区

分享

第十三章 文 件

 running_to_you 2017-05-12

第十三章

13.1 C文件概述

文件:文件指存儲在外部介質(zhì)(如磁盤磁帶)上數(shù)據(jù)的集合。

操作系統(tǒng)是以文件為單位對數(shù)據(jù)進(jìn)行管理的。

 

文件的分類

●從用戶觀點(diǎn):

特殊文件(標(biāo)準(zhǔn)輸入輸出文件或標(biāo)準(zhǔn)設(shè)備文件)。

普通文件(磁盤文件)。

●從操作系統(tǒng)的角度看,每一個(gè)與主機(jī)相連的輸入

輸出設(shè)備看作是一個(gè)文件。

例:輸入文件:終端鍵盤

輸出文件:顯示屏和打印機(jī)

1)根據(jù)文件的內(nèi)容,可分為程序文件和數(shù)據(jù)文件,程序文件又可分為源文件、目標(biāo)文件和可執(zhí)行文件。

2)根據(jù)文件的組織形式,可分為順序存取文件和隨機(jī)存取文件。

3)根據(jù)文件的存儲形式,可分為ASCII碼文件和二進(jìn)制文件。

 ASCII碼文件的每1個(gè)字節(jié)存儲1個(gè)字符,因而便于對字符進(jìn)行逐個(gè)處理。但一般占用存儲空間較多,而且要花費(fèi)轉(zhuǎn)換時(shí)間(二進(jìn)制與ASCII碼之間的轉(zhuǎn)換)。

二進(jìn)制文件是把內(nèi)存中的數(shù)據(jù),原樣輸出到磁盤文件中。可以節(jié)省存儲空間和轉(zhuǎn)換時(shí)間,但1個(gè)字節(jié)并不對應(yīng)1個(gè)字符,不能直接輸出字符形式。

C語言對文件的處理方法:

緩沖文件系統(tǒng):系統(tǒng)自動(dòng)地在內(nèi)存區(qū)為每一個(gè)正在使用的文件開辟一個(gè)緩沖區(qū)。用緩沖文件系統(tǒng)進(jìn)行的輸入輸出又稱為高級磁盤輸入輸出。

非緩沖文件系統(tǒng):系統(tǒng)不自動(dòng)開辟確定大小的緩沖區(qū),而由程序?yàn)槊總€(gè)文件設(shè)定緩沖區(qū)。用非緩沖文件系統(tǒng)進(jìn)行的輸入輸出又稱為低級輸入輸出系統(tǒng)。

說明:

UNIX系統(tǒng)下,用緩沖文件系統(tǒng)來處理文本文件,用非緩沖文件系統(tǒng)來處理二進(jìn)制文件。

ANSI C 標(biāo)準(zhǔn)只采用緩沖文件系統(tǒng)來處理文本文件和二進(jìn)制文件。

C語言中對文件的讀寫都是用庫函數(shù)來實(shí)現(xiàn)。

13.2 文件類型指針

Turbo C在stdio.h文件中有以下的文件類型聲明:

typedef struct

shortlevel;   *緩沖區(qū)“滿”或“空”的程度*

   unsignedflags; *文件狀態(tài)標(biāo)志*

   charfd;        *文件描述符*

   unsignedcharhold; *如無緩沖區(qū)不讀取字符*

   shortbsize;       *緩沖區(qū)的大小*

   unsignedchar*buffer;/*數(shù)據(jù)緩沖區(qū)的位置*/

   unsignedar*curp;/*指針,當(dāng)前的指向*/

   unsignedistemp;/*臨時(shí)文件,指示器*/

   shorttoken;/*用于有效性檢查*/FILE

在緩沖文件系統(tǒng)中,每個(gè)被使用的文件都要在內(nèi)存中開辟一

FILE類型的區(qū),存放文件的有關(guān)信息。

FILE類型的數(shù)組:

FILE f5;定義了一個(gè)結(jié)構(gòu)體數(shù)組f,它有5個(gè)元素,可以用來存放5個(gè)文件的信息。

文件型指針變量:

FILE  *fp;fp是一個(gè)指向FILE類型結(jié)構(gòu)體的指針變量。可以使fp指向某一個(gè)文件的結(jié)構(gòu)體變量,從而通過該結(jié)構(gòu)體變量中的文件信息能夠訪問該文件。如果有n個(gè)文件,一般應(yīng)設(shè)n個(gè)指針變量,使它們分別指向n個(gè)文件,以實(shí)現(xiàn)對文件的訪問。

13.3 文件的打開與關(guān)閉

.文件的打開(fopen函數(shù))

函數(shù)調(diào)用:

FILE  *fp;

fpfopen(文件名,使用文件方式);

①需要打開的文件名,也就是準(zhǔn)備訪問的文件的名字;

②使用文件的方式(“讀”還是“寫”等);

③讓哪一個(gè)指針變量指向被打開的文件。

.文件的關(guān)閉(fclose函數(shù))

函數(shù)調(diào)用:

fclose(文件指針);

函數(shù)功能:

使文件指針變量不指向該文件,也就是文件指針變量與文件“脫鉤”,此后不能再通過該指針對原來與其相聯(lián)系的文件進(jìn)行讀寫操作。

返回值:

關(guān)閉成功返回值為0;否則返回EOF(-1)

13.4 文件的讀寫

一、字符輸入輸出函數(shù)(fputs()fgets())

1.fputs函數(shù)

函數(shù)調(diào)用:

fputs ( chfp )

函數(shù)功能:

將字符(ch的值)輸出到fp所指向的文件中去。

返回值:

如果輸出成功,則返回值就是輸出的字符;

如果輸出失敗,則返回一個(gè)EOF。

2.fgets函數(shù)

函數(shù)調(diào)用:

chfgetsfp);

函數(shù)功能:

從指定的文件讀入一個(gè)字符,該文件必須是以讀或讀寫方式打開的。

返回值:

讀取成功一個(gè)字符,賦給ch。

如果遇到文件結(jié)束符,返回一個(gè)文件結(jié)束標(biāo)志EOF 。

常見的讀取字符操作

從一個(gè)文本文件順序讀入字符并在屏幕上顯示出來:

   ch = fgetcfp);

   whilech!=EOF

  {

       putcharch);

        ch = fgetcfp);

 

注意:EOF不是可輸出字符,因此不能在屏幕上顯示。由于字符的ASCII碼不可能出現(xiàn)-1,因此EOF定義為-1是合適的。當(dāng)讀入的字符值等于-1時(shí),表示讀入的已不是正常的字符而是文件結(jié)束符。

常見的讀取字符操作

從一個(gè)二進(jìn)制文件順序讀入字符:

   while(!feoffp))

  {

        ch = fgetcfp);

 

注意:ANSI C提供一個(gè)feof()函數(shù)來判斷文件是否真的結(jié)束。如果是文件結(jié)束,函數(shù)feoffp)的值為1(真);否則為0(假)。以上也適用于文本文件的讀取。

#include <stdlib.h>

#include <stdio.h>

void   main(void)

 {     FILE *fp;

       char ch,filename[10];

       scanf("%s",filename);

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

{

                  printf("cannot open file\n");

                  exit(0); /*終止程序*/

}

       ch=getchar( ); /*接收執(zhí)行scanf語句時(shí)最后輸入的回車符 */

       ch=getchar( ); /* 接收輸入的第一個(gè)字符 */

       while(ch!='#)

       {

fputc(ch,fp);putchar(ch);

                           ch=getchar();

}

                     fclose(fp);

     }

運(yùn)行情況如下:
file1.c              (輸入磁盤文件名)
computer and c#(輸入一個(gè)字符串)
computer and c    (輸出一個(gè)字符串)

 

 

 


#include <stdlib.h>

#include <stdio.h>

 main( )

{

FILE *in,*out;

        char ch,infile[10],outfile[10];

        printf("Enter the infile name:\n");

scanf("%s",infile);

        printf("Enter the outfile name:\n");

        scanf("%s",outfile);

        if((in=fopen(infile,"r"))==NULL)

        {       

printf("cannot open infile\n");

           exit(0);

}

        if((out=fopen(outfile,"w"))==NULL)

    {       

printf("cannot open outfile\n");

        exit(0);

    }

    while(!feof(in))fputc(fgetc(in),out);

    close(in);

        fclose(out);

}

運(yùn)行情況如下:
Enter the infile name
file1.c(輸入原有磁盤文件名
Enter the outfile name:
file2.c (輸入新復(fù)制的磁盤文件名) 
程序運(yùn)行結(jié)果是將file1.c文件中的內(nèi)容復(fù)制到
file2.c中去。 

 

#include <stdlib.h>

#include <stdio.h>

main(int argc,char *argv[ ])

{

FILE *in,*out;

        char ch;

        if (argc!=3)

 {     

printf("You forgot to enter a filename\n");

                   exit(0);

 }

         if((in=fopen(argv[1],"rb"))==NULL)

         {       

printf("cannot open infile\n");

             exit(0);

}

    if((out=fopen(argv[2],"wb"))==NULL)

         {       

printf("cannot open outfile\n");

             exit(0);

}

         while(!feof(in)) fputc(fgetc(in),out);

        fclose(in);

 fclose(out);

}

運(yùn)行方法:
設(shè)經(jīng)編譯連接后得到的可執(zhí)行文件名為a.exe,則在DOS命令工
作方式下,可以輸入以下的命令行:
C>a?。妫椋欤澹保恪。妫椋欤澹玻?
file1.c和file2.c,分別輸入到argv[1]
和argv[2]中,argv[0]的內(nèi)容為a,argc的
值等于3 。

 

 

 

 

 

二、數(shù)據(jù)塊讀寫函數(shù)(fread()fwrite())

函數(shù)調(diào)用:

fread (buffer,size,countfp);

fwrite(buffer,size,count,fp);

參數(shù)說明:

buffer:是一個(gè)指針。

fread 來說,它是讀入數(shù)據(jù)的存放地址。

fwrite來說,是要輸出數(shù)據(jù)的地址(均指起始地址)。

size  要讀寫的字節(jié)數(shù)。

count 要進(jìn)行讀寫多少個(gè)size字節(jié)的數(shù)據(jù)項(xiàng)。

fp    文件型指針。

使用舉例:

  若文件以二進(jìn)制形式打開:

  fread(f,4,2,fp);

  此函數(shù)從fp所指向的文件中讀入2個(gè)4個(gè)字節(jié)的數(shù)據(jù),存儲到數(shù)組f中。

使用舉例:

若有如下結(jié)構(gòu)類型:

struct student_type

{

char name[10];

int num;

        int age;

        char addr[30];}stud[40];

}

可以用freadfwrite來進(jìn)行數(shù)據(jù)的操作:

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

 fread(&studi],sizeof(struct student-type),1fp); 

for(i=0;i<40,i++)

fwrite(&studi],sizeof(struct student-type),1,fp); 

使用舉例:

13.3從鍵盤輸入4個(gè)學(xué)生的有關(guān)數(shù)據(jù),然后把它們轉(zhuǎn)存到磁盤文件上去。

#include <stdio.h>

#define SIZE 4

struct student_type

{        char name[10];

    int num;

    int age;

    char addr[15];

}stud[SIZE]; /*定義結(jié)構(gòu)*/

void save( )

{

FILE *fp;

        int i;

        if((fp=fopen("stu-list","wb"))==NULL)

{

 printf("cannot open file\n");

                return;

}

        for(i=0;i<SIZE;i++)/*二進(jìn)制寫*/

if(fwrite(&stud[i],sizeof(struct student_type),1,fp)!=1)

                 printf(file write error\n);/*出錯(cuò)處理*/

        fclose(fp); } /*關(guān)閉文件*/  

main()

{

int i;

                 for(i=0;i<SIZE;i++)/*從鍵盤讀入學(xué)生信息*/

scanf("%s%d%d%s",stud[i].name,&stud[i].num,&stud[i].age,stud[i].addr);

    save( );

}/*調(diào)用save()保存學(xué)生信息*/

運(yùn)行情況如下:
輸入4個(gè)學(xué)生的姓名、學(xué)號、年齡和地址:
       Zhang?。保埃埃薄。保埂。颍铮铮?101
       Fun      1002  20  room-102
       Tan      1003  21  room-103
       Ling    1004  21  room-104 

 

 

 

 


 #include <stdio.h>

 #define SIZE 4

 struct student_type

 {        char name[10];

      int num;

      int age;

      char addr[15];

}stud[SIZE];    

 main( )

{        int i;

         FILE*fp;

         fp=fopen("stu-list","rb");

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

    {

fread(&stud[i],sizeof(struct student_type),1,fp);

            printf("%\-10s %4d      %4d   %\-15s\n",stud[i].name,stud[i].num,stud[i].          age,stud[i].addr);

}

         fclose (fp);

    }

屏幕上顯示出以下信息:
Zhang 1001      19    room-101
Fun     1002      20    room-102
Tan     1003      21    room-103
Ling   1004      21    room-104 

 

 

 

如果已有的數(shù)據(jù)已經(jīng)以二進(jìn)制形式存儲在一個(gè)磁盤文件“stu-dat”中,要求從其中讀入數(shù)據(jù)并輸出到“stu-list”文件中,可以編寫一個(gè)load函數(shù),從磁盤文件中讀二進(jìn)制數(shù)據(jù)。

void load( )

 {

FILE *fp;int i;

       if((fp=fopen("stu-dat","rb"))==NULL)

    {       

printf("cannot open infile\n");

           return;

}

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

             if(fread(&stud[i],sizeof(struct student_type),1,fp)!=1)

           {

if(feof(fp)) {fclose(fp); return;}

                         printf("file read error\n");

}

  fclose (fp);

}

三、格式化讀寫函數(shù)(fprintf()fscanf())

函數(shù)調(diào)用:

fprintf ( 文件指針,格式字符串,輸出表列);

fscanf  ( 文件指針,格式字符串,輸入表列);

函數(shù)功能:

從磁盤文件中讀入或輸出字符。

例:

fprintf(fp,%d,%6.2f,i,t);

Fscanf (fp,%d,%f,&i,&t);

注意:

fprintffscanf函數(shù)對磁盤文件讀寫,使用方便,容易理解,但由于在輸入時(shí)要將ASCII碼轉(zhuǎn)換為二進(jìn)制形式,在輸出時(shí)又要將二進(jìn)制形式轉(zhuǎn)換成字符,花費(fèi)時(shí)間比較多。因此,在內(nèi)存與磁盤頻繁交換數(shù)據(jù)的情況下,最好不用fprintffscanf函數(shù),而用freadfwrite函數(shù)。

四、其他讀寫函數(shù)

putw()getw()

函數(shù)調(diào)用:

putw(int i,FILE * fp)

int i = getw(FILE * fp);

函數(shù)功能:

對磁盤文件中讀寫一個(gè)字(整數(shù))。

例:

putw(10,fp);

i = getw(fp);

gutw函數(shù)定義如下:

gutw(FILE *fp)

{

   char s;

   s=char *&i;

   s[0] = getc(fp);

   s[1] = getc(fp);

   return i;

  }

用戶自定義讀取其他類型數(shù)據(jù)的函數(shù)。

向磁盤文件寫一個(gè)實(shí)數(shù)(用二進(jìn)制方式)的函數(shù)putfloat :

putfloat(float num,FILE *fp)

{

         char *s;

         int count;

         s = (char*)&num;

         for(count = 0;count < 4;count++)

         putc(s[count],fp);

 }

fgets函數(shù)

函數(shù)作用:

從指定文件讀入一個(gè)字符串。

函數(shù)調(diào)用:

fgets(str,n,fp);

fp指向的文件輸入n-1個(gè)字符,在最后加一個(gè)’\0’。

返回值:

str的首地址。

fputs函數(shù)

函數(shù)作用:

向指定的文件輸出一個(gè)字符串。

函數(shù)調(diào)用:

fgets(china,fp);

第一個(gè)參數(shù)可以是字符串常量、字符數(shù)組名或字符型指針。字符串末尾的′\0′不輸出。

返回值:

輸入成功,返回值為0

輸入失敗,返回EOF

13.5 文件的定位

#include<stdio.h>

 main()

{        FILE *fp1,*fp2;

        fp1=fopen("file1.c","r");

         fp2=fopen("file2.c","w");

    while(!feof(fp1)) putchar(getc(fp1));

     rewind(fp1);

          while(!feof(fp1))

     putc(getc(fp1),fp2);

     fclose(fp1);fclose(fp2);

}

順序讀寫和隨機(jī)讀寫

順序讀寫:

位置指針按字節(jié)位置順序移動(dòng)。

隨機(jī)讀寫:

讀寫完上一個(gè)字符(字節(jié))后,并不一定要讀寫其后續(xù)的字符(字節(jié)),而可以讀些文件中任意位置上所需要的字符(字節(jié))。

fseek函數(shù)(一般用于二進(jìn)制文件)

函數(shù)功能:

改變文件的位置指針。

函數(shù)調(diào)用形式:

fseek(文件類型指針,位移量,起始點(diǎn))

起始點(diǎn):文件開頭         SEEK_SET     0

        文件當(dāng)前位置     SEEK_CUR     1

        文件末尾         SEEK_END     2

位移量:以起始點(diǎn)為基點(diǎn),向前移動(dòng)的字節(jié)數(shù)。一般

        要求為long型。

fseek函數(shù)應(yīng)用舉例

fseek(fp,100L,0);//將位置指針移到離文件頭100個(gè)字節(jié)處。

fseek(fp50L, 1);//將位置指針移到離當(dāng)前位置50個(gè)字節(jié)處。

fseek(fp50L, 2);//將位置指針從文件末尾處向后退10個(gè)字節(jié)。

#include <stdlib.h>

#include<stdio.h>

 struct student_type

{       char name[10];

        int num;

        int age;

        char sex;

 }stud[10];   

 main()

{  int i;

   FILE  *fp;

   if((fp=fopen("stud-dat","rb"))==NULL)

   {

printf("can not open file\n");

             exit(0);

   }

  for(i=0;i<10;i+=2)

  {

    fseek(fp,i*sizeof(struct student_type),0);

      fread(&stud[i], sizeof(struct student_type),1,fp);

      printf(%s %d %d %c\n,stud[i].name,stud[i].num,stud[i].age,stud[i].sex);

}

 fclose(fp);

}

ftell函數(shù)

函數(shù)作用:

得到流式文件中的當(dāng)前位置,用相對于文件開頭的位移量來表示。

返回值:

返回當(dāng)前位置,出錯(cuò)時(shí)返回-1L。

應(yīng)用舉例:

i = ftell(fp);

if(i==-1L) printf(error\n);

13.6 出錯(cuò)的檢測

ferror函數(shù)

調(diào)用形式:

ferror(fp);

返回值:

返回0,表示未出錯(cuò);返回非0,表示出錯(cuò)。

在調(diào)用一個(gè)輸入輸出函數(shù)后立即檢查ferror函數(shù)的值,否則信息會丟失。在執(zhí)行fopen函數(shù)時(shí),ferror函數(shù)的初始值自動(dòng)置為0。

clearerr函數(shù)

調(diào)用形式:

clearerr(fp);

函數(shù)作用:

使文件錯(cuò)誤標(biāo)志和文件結(jié)束標(biāo)志置為0

只要出現(xiàn)錯(cuò)誤標(biāo)志,就一直保留,直到對同一文件調(diào)用clearerr函數(shù)或rewind函數(shù),或任何其他一個(gè)輸入輸出函數(shù)。

13.7 文件輸入輸出小結(jié)

 

 

 

 

 

    本站是提供個(gè)人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多

    欧美大粗爽一区二区三区| 欧美日韩国产精品第五页| 日韩av生活片一区二区三区| 久久精品国产熟女精品| 成人免费在线视频大香蕉| 视频一区二区 国产精品| 日韩午夜老司机免费视频| 国产日韩欧美专区一区| 日韩国产亚洲欧美激情| 国产日产欧美精品大秀| 国产精品99一区二区三区| 日本亚洲精品在线观看| 国产精品亚洲一区二区| 国产伦精品一一区二区三区高清版 | 色偷偷偷拍视频在线观看| 国产欧美日产中文一区| 九九久久精品久久久精品| 正在播放国产又粗又长| 亚洲欧美国产网爆精品| 97人摸人人澡人人人超碰| 日韩综合国产欧美一区| 国产毛片av一区二区三区小说| 久久91精品国产亚洲| 日韩欧美亚洲综合在线| 中文字幕中文字幕在线十八区| 亚洲a码一区二区三区| 国产又粗又猛又长又黄视频| 国产综合一区二区三区av| 欧美激情视频一区二区三区| 尤物天堂av一区二区| 99久久免费中文字幕| 午夜成年人黄片免费观看| 欧美日韩黑人免费观看| 国产一区二区三区成人精品| 欧美日韩成人在线一区| 日韩欧美中文字幕av| 日本人妻中出在线观看| 亚洲国产成人一区二区在线观看| 国产传媒中文字幕东京热| 国产精品十八禁亚洲黄污免费观看 | 不卡视频在线一区二区三区|