語(yǔ)言文件系統(tǒng)稱為流文件(Stream),正文流(正文文件),二進(jìn)制流(二進(jìn)制文件)

  • 緩沖與非緩沖文件
  • 順序操作文件與隨機(jī)操作文件
    • 順序文件:讀/寫第K個(gè)數(shù)據(jù)塊之前必須讀/寫第1至K-1個(gè)數(shù)據(jù)塊;
    • 隨機(jī)文件:可直接讀/寫第K個(gè)數(shù)據(jù)塊;
  • 正文文件的操作一般是順序文件;
  • 二進(jìn)制文件的操作都是隨機(jī)文件。


    一、文件操作的一般過程

定義文件指針 FILE *
打開文件 fopen
對(duì)文件進(jìn)行讀寫

二、系統(tǒng)已定義的與文件操作有關(guān)的數(shù)據(jù)結(jié)構(gòu)全都在stdio.h中

  1. FILE 結(jié)構(gòu)體

       FILE *fr,*fp,*fw;

    FILE* 指針作為文件句柄,是文件訪問的唯一標(biāo)識(shí),它由fopen函數(shù)創(chuàng)建,fopen打開文件成功,則返回一個(gè)有效的FILE*指針,否則返回空指針NULL

  2. 標(biāo)準(zhǔn)文件指針

       FILE *stdin,*stdout,*stderr,
       stdin 指鍵盤輸入
       stdout 指顯示器
       stderr 指出錯(cuò)輸出設(shè)備,也指顯示器

    這些變量已成功初始化,可直接使用.

三、常用操作函數(shù)

  1. fopen

    格式:FILE *fopen(文件名字符串,打開方式串)

    例:FILE *fr; fr=fopen("c:\\user\\abc.txt","r");

    字符串操作:

    1)"r"或"rt":正文文件只讀方式打開。文件不存在,則打開失敗(順序讀)"w"或"wt":正文文件只寫方式打開。若文件不存在,則建立文件;若文件存在,則刪除文件內(nèi)容,重建空文件(順序?qū)懀唬ń厝∥募L(zhǎng)度為0)

    2) "a"或"at":正文文件添加方式。文件不存在,則建立文件(順序添加寫)

    3) "r+"或"rt++":正文文件讀寫打開,文件不存在,則打開失敗(順序讀/寫、隨機(jī)讀/寫,含改寫與添加);

    4) "w+"或"w++":正文文件讀寫方式打開,文件不存在,則建立文件;否則截取文件長(zhǎng)度為0(順序讀/寫,隨機(jī)讀/寫,對(duì)寫入的內(nèi)容可以讀或改寫或添加)

    5) ~b:正文文件→二進(jìn)制文件
      順序讀→順序/隨機(jī)讀(“rb”)

      eg:"r"或"rt"→"rb"
       順序?qū)?"wb")
       順序添加寫("ab")
       順...,隨...,含...("rb+")
       順...,添加("wb+")
       順...,添加("ab+")

    使用fopen時(shí),但凡含r字母的打開方式,一定要加判斷,文件是否打開成功,否則程序不會(huì)報(bào)告錯(cuò)誤,會(huì)運(yùn)行下去。

    如:FILE *fr;
    fr=fopen("abc.txt","r");
    if(fr==NULL){
    printf("File not open!\n");
    return; /*或exit(1);*/

  2. 文件關(guān)閉

    fclose(FILE *fp)

    一般地,fclose(fp)與fopen應(yīng)配對(duì)使用,特別是含有寫方式的文件,若不關(guān)閉會(huì)造成文件數(shù)據(jù)丟失。

    fcloseall(void):關(guān)閉當(dāng)前所有打開的文件。

  3. 單字節(jié)的輸入函數(shù)

    可適用于二進(jìn)制與正文文件操作
    int fgetc(FILE *fp)
       int fputc(char ch.FILE *fp)

    fgetc的返回值都是正數(shù)(0~255)

    文件無可讀字節(jié)則返回-1(EOF)

    正文文件與二進(jìn)制文件讀寫的區(qū)別:
    正文文件讀到13 10時(shí),將自動(dòng)跳過13,讀出10并返回;正文文件寫入10時(shí),首先自動(dòng)寫入13再寫入10.

  4. 文件指針與文件指針操作函數(shù)

    文件指針是文件操作系統(tǒng)數(shù)據(jù)結(jié)構(gòu)內(nèi)部的一種數(shù)據(jù)指針,它用于標(biāo)注文件當(dāng)前讀寫位置,C語(yǔ)言中,文件指針以字節(jié)為單位,文件第一個(gè)字節(jié)位置號(hào)為0,若文件長(zhǎng)度為N個(gè)字節(jié),則最后一個(gè)字節(jié)的位置號(hào)為N-1,長(zhǎng)度為N字節(jié)的文件有效讀寫范圍為0~N-1。指針位置在此之外進(jìn)行讀/寫操作,則失敗;讀寫函數(shù)返回-1(EOF);

    C語(yǔ)言的文件指針采用long型值;

    執(zhí)行文件讀/寫操作后,文件指針自動(dòng)向后移動(dòng),指到新的待讀/寫位置。

    文件指針移動(dòng)函數(shù)
    rewind(FILE *fp)
    文件指針重置為0
    fseek(FILE *fp,long off,int pos)
       從pos位置開始,移動(dòng)off個(gè)字節(jié)。

    pos: 0 文件開始
          1 文件當(dāng)前指針位置
          2 文件結(jié)尾(文件長(zhǎng)度為N,則指針位置為N)

    例:fseek(fp,0l,0);←→rewind(fp)
    fseek(fp,-1L,2); /*移動(dòng)指針到最后一個(gè)字節(jié)*/
    fseek(fp,-2L,1); /*移動(dòng)指針到當(dāng)前位置的前兩個(gè)位置*/
    long ftell(FILE *fp)

    求當(dāng)前指針位置

    例:求文件長(zhǎng)度
    fseek(fp,OL,2);
    len=ftell(fp);
    則len為文件長(zhǎng)度


    文件指針的特性:

  • 可在“負(fù)無窮”到“正無窮”任意移動(dòng);
  • 在0~N-1之外進(jìn)行讀操作,則讀失敗;讀失敗后,feof函數(shù)為真;
  • 從N位置開始寫入,則為添加;
  • 從0~N位置之外開始寫也可,其行為不必掌握,因?yàn)閹缀鯚o用;
  • 無論任何方式,剛打開文件時(shí),ftell函數(shù)返回值都是0,含a方式的文件,只要一寫(第一次寫),文件指針自動(dòng)移動(dòng)到N位置處。
    int feof(FILE *fp)
    若文件讀失敗,則返回非0值,否則返回0值;僅用于讀是否到文件尾。
    任何fseek操作使feof為假,即使文件指針在0~N-1之外。
  1. 正文文件讀/寫函數(shù)
    fscanf(fp...)
       fprintf(fp...)

    其中,...與scanf和printf用法完全相同.
    scanf(...)←→fscanf(stdin...)
    printf(...)←→fprintf(stdout...)

  2. 二進(jìn)制文件讀/寫函數(shù),即字節(jié)塊函數(shù)
    int fread(char *buf,int size,int count,FILE *fp)
       int fwrite(char *buf,int&nbtp;size,int count,FILE *fp)
    從文件讀出size x count個(gè)字節(jié)到內(nèi)存塊buf;從內(nèi)存塊buf寫入size x count個(gè)字節(jié)到文件,返回實(shí)際讀出/寫入的字節(jié)數(shù)。


?



一、文件中刪除第K個(gè)記錄:拷貝0~K-1,K+1~N條記錄到一個(gè)臨時(shí)文件,刪除源文件,將源文件改名為源文件。

二、讀/改寫第K個(gè)記錄:移動(dòng)指針到第K個(gè)記錄,用fread,fwrite改寫。

三、添加記錄(略)

四、插入記錄

  1. 復(fù)制臨時(shí)文件
  2. 插入到K號(hào)記錄之前:先將N-1寫入N位置,N-2寫入N-1,直到K寫入K+1位置:用待插入記錄改寫K位置。(建立時(shí)用rb+方式打開)

    #include "tdio.h"
    void main()
    {FILE *fp;char ch1,ch2;long pos1,pos2,p;
    char fname[81];
    printf("Input C source filename:");
    gets(fname);
    fp=fopen(fname,"r+");
    if(!fp){printf("FILE not found .\n); return;
    ch1=fgetc(fp);
    while(!feof(fp))
    {cha2=fgetc(fp);if(feof(fp)) break;
    if(ch1=='/'&&ch2=='*')
    {pos1=ftell(fp)-2;
    }
    if(ch1=='*'&&ch=='/')
    {pos2=ftell(fp)-1;
    fseek(fp,pos1,0);
    for(p=pos1;p<=pos2;p++) fputc(32,fp);
    fseek(fp,OL,1);
    }
    ch1=ch2;
    }
    fclose(fp);