C語言-文件

所謂“文件”是指一組相關(guān)數(shù)據(jù)的有序集合洛巢,該數(shù)據(jù)的集合的名字就是文件名。文件可以分為很多類次兆,如源程序文件稿茉、目標(biāo)文件、可執(zhí)行文件芥炭、庫文件等等漓库。
文件通常是存放在外部介質(zhì)上的(例如磁盤等),在使用時才會被調(diào)入內(nèi)存中并執(zhí)行园蝠。從用戶的角度來看文件可以分為普通文件和設(shè)備文件米苹。
普通文件是指存放在磁盤或者其它外部介質(zhì)上的一個有序的集合,可以是源文件砰琢、目標(biāo)文件蘸嘶、可執(zhí)行程序等;也可以是一組待輸入處理的原始數(shù)據(jù)陪汽,或是一組輸出的結(jié)果训唱。對于源文件、目標(biāo)文件挚冤、可執(zhí)行程序可以稱作程序文件况增,而輸入輸出數(shù)據(jù)可以稱作數(shù)據(jù)文件。
設(shè)備文件是指與主機相聯(lián)的各種外部設(shè)備训挡,如顯示器澳骤、打印機、鍵盤等澜薄。在操作系統(tǒng)中为肮,把外部設(shè)備也看作是一個文件來進行管理,把他們的輸入輸出等同于對磁盤文件的讀寫肤京。
從文件編碼的形式來看颊艳,文件可以分為ASCII碼文件和二進制碼文件。ASCII碼文件也稱作為文本文件,這種文件在磁盤中存放時每個字符對應(yīng)一個字節(jié)棋枕,用于存放相應(yīng)的ASCII碼白修。
二進制文件是以二進制編碼的方式來編寫文件的。二進制文件雖然可以顯示在屏幕上重斑,但是卻不能讀懂兵睛。

文件的指針

在C語言中用一個指針變量指向一個文件,那么這個指針稱為文件指針窥浪。另外祖很,我們通過文件指針就可以對所指的文件進行各種操作。

一般形式為:
FILE* 文件變量標(biāo)識符

解釋:FILE應(yīng)該是大寫的寒矿,它實際上是由系統(tǒng)定義的一個結(jié)構(gòu)體突琳,該結(jié)構(gòu)體包含了文件名、文件狀態(tài)和文件當(dāng)前位置等信息符相,因此在編寫程序的時候我們不需要過于關(guān)心FILE結(jié)構(gòu)的細節(jié)部分拆融。

// 案例1:
FILE *fp;
/*說明:
fp表示FILE結(jié)構(gòu)的指針變量啊终,通過fp可以找到存放某一個文件信息的結(jié)構(gòu)變量镜豹,
然后按照結(jié)構(gòu)體提供的信息找到該文件,并對文件進行操作蓝牲。*/

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

文件在進行讀寫操作之前趟脂,要打開文件,當(dāng)使用完后應(yīng)關(guān)閉文件例衍。打開文件就是建立文件的各種有關(guān)信息昔期,并使文件指針指向文件,以便進行其他操作佛玄。而關(guān)閉文件就是切斷文件指針和文件之間的關(guān)系硼一,換而言之,就是禁止利用指針操作文件梦抢。
在C語言中般贼,文件操作都是由庫函數(shù)完成的。如fopen 和 fclose奥吩。

1. 文件的打開 fopen()

fopen() 函數(shù)是用來打開一個文件哼蛆,其一般的調(diào)用形式為:
文件指針名 = fopen(文件名,使用文件的方式)霞赫;

注釋:

  1. 文件指針名:必須被說明為FILE類型的指針變量腮介;
  2. 文件名:被打開文件的文件名;
  3. 使用文件的方式:文件的類型和操作要求
// 案例2:
FILE* fp;
fp = fopen("text","r");
/*說明:
在當(dāng)前目錄下打開文件text绩脆,只允許“讀”的操作萤厅,并且讓fp指針指向該文件*/

使用文件的方式有12種橄抹,如下所示:

|使用文件方 | 意義                                                              |
|----------|------------------------------:|
|“rt”      | 只讀打開一個文本靴迫,只允許讀|
|“wt”      | 只寫打開或者建立一個文件惕味,只允許寫數(shù)據(jù)|
|“at”      | 追加打開一個文件,并在文件末尾寫數(shù)據(jù)|
|“rb”      | 只讀打開一個二進制文件玉锌,只允許讀|
|“wt”      | 只寫打開或者建立一個而進制文件名挥,只允許寫|
|“ab”      | 追加打開一個二進制文件,并在文件末尾寫數(shù)據(jù)|
|“rt+”     | 讀寫打開一個文件主守,允許讀和寫 |
| “wt+”    | 讀寫打開或建立一個文件禀倔,允許讀寫|
|“at+”     | 讀寫打開一個文件,允許讀参淫,或在文件末尾追加數(shù)據(jù)|
|“rb+”     | 讀寫打開一個二進制文件救湖,允許讀寫|
|“wb+”     | 讀寫打開或者建立一個二進制文件,允許讀寫        |
|“ab+”     | 讀寫打開一個二進制文件涎才,允許讀鞋既,或在文件末追加數(shù)據(jù)|

說明:
由r、w耍铜、a邑闺、t、b棕兼、+六個字符拼成陡舅,個字符的意義:

  1. r(read):讀
  2. w(write):寫
  3. a(append):追加
  4. t(text):文本文件,可省略不寫
  5. b(banary):二進制文件
    6.+:讀和寫
// 案例3:
FILE* fp;
fd = fopen("./text","r");
if (NULL == fd)
{
    printf("open error\n");
    exit(1);
}
// 用讀“r”的方式打開文件“./text”伴挚;若文件打開失敗時靶衍,fp為空,輸出open error茎芋。

2. 文件的關(guān)閉

fclose()函數(shù)是指當(dāng)文件使用完后颅眶,需要關(guān)閉文件。其一般形式為:
fclose(文件指針)败徊;

// 案例4:
fclose(fp);
// 說明:正常關(guān)閉文件時帚呼,fclose()函數(shù)的返回值是0。若返回一個非零的值皱蹦,則表示關(guān)閉文件時發(fā)生錯誤

文件的讀寫

文件的讀寫是有多重方式的煤杀,它可以一個字節(jié)一個字節(jié)的讀或?qū)懀部梢允且淮淮淖x或?qū)懟Σ浮N募淖x寫可以分為下面四類沈自,且它們的頭文件均是<stdio.h>。

1. 字符讀寫函數(shù)fgetc 和 fputc

字符的讀寫函數(shù)是以字節(jié)為單位讀寫函數(shù)辜妓。每一次可以從文件讀出或向文件內(nèi)寫入一個字符枯途。
讀字符函數(shù)fgetc() 的一般形式:
字符變量 = fgetc(文件指針)忌怎;

說明:將文件中的一個字符讀取出來,然后存放在字符變量中酪夷。

寫字符函數(shù)fputs() 的一般形式:
fputs(字符量榴啸,文件指針);

說明:將字符量中的字符晚岭,存放在想對應(yīng)的文件中鸥印。

// 案例5:
#include<stdio.h>

int main()
{
    FILE* fp = fopen("./text","r");
    if (NULL == fp)
    {
      printf("cann't open the file\n");
      exit(1);
    }
    char ch; 
    // 讀取文件中的字符,一個一個的讀取坦报。
    ch = fgetc(fp);
    while (EOF != ch)  // EOF表示讀到文件的末尾
    {
      printf("%c\n",ch);
      ch = fgetc(fp);
    }
    close(fp);
    // 向文件中寫入數(shù)據(jù)
    fp = fopen("./text1","w");
    if (NULL == fp)
    {
      printf("cann't open the file\n");
      exit(1);
    }
    printf("input a character:");
    scanf("%c",&ch);
    fputc(ch,fp); // 將ch變量中的字符存放到文件“./text1”中库说。
    return 0;
}

注意:在網(wǎng)文件中寫數(shù)據(jù)的時候,上的那種寫法是片择,直接覆蓋文件中的數(shù)據(jù)潜的,而不是在文件的末尾追加數(shù)據(jù)。若想不改變文件原來的數(shù)據(jù)字管,只想在文件的末尾追加數(shù)據(jù)啰挪,那么需要將文件的打開方式“w”更改為“a”,這樣我們就可以在原數(shù)據(jù)的基礎(chǔ)上追加數(shù)據(jù)纤掸。

2. 字符串讀寫函數(shù)fgets 和 fputs

fgets() 的一般形式:
fgets(字符數(shù)組名脐供,n,文件指針)借跪;

說明:n是一個正整數(shù)政己,表示從文件中讀取的字符串不超過n-1個字符,在讀入最后一個字符后加上結(jié)束符'\0'掏愁。

fputs()的一般形式:
fputs(字符數(shù)組名歇由,文件指針);

說明:字符數(shù)組名果港,首先其中必須是一個已被初始化的字符數(shù)組沦泌,即里面有值;也可以用一個字符串常量(或指針變量)代替字符數(shù)組名辛掠。

//案例6:
#include<stdio.h>

int main()
{
    char ch[20];
    FILE *fp = fopen("./text","rw");
    if (NULL == fp)
    {
      printf("open error\n");
      exit(1);
    }
    printf("input what you want to say:");
    scanf("%s",ch);
    //將字符串ch中的值寫在文件text中谢谦。
    fputs(ch,fp);
    char ch2[30];
    // 從文件中讀取數(shù)據(jù),并由ch2字符串變量接收萝衩。
    fgets(ch2,sizeof(ch2)-1,fp);
    printf("ch2:%s\n",ch2);
    return 0;
}

3. 數(shù)據(jù)塊讀寫函數(shù)fread 和fwrite

C語言中不僅提供了字符回挽、字符串的讀寫方式,同時也提供了數(shù)據(jù)塊的讀寫方式猩谊。它們可用來讀寫一組數(shù)據(jù)千劈,如:一個數(shù)組元素,一個結(jié)構(gòu)變量的值等牌捷。
fread()的一般形式:
fread(buffer墙牌,size涡驮,count,fp);
fwrite()的一般形式:
fwrite(buffer喜滨,size捉捅,count,fp)鸿市;

說明:

  1. buffer 是一個指針锯梁,在fread函數(shù)中表示存放數(shù)據(jù)的首地址即碗。在fwrite函數(shù)中表示輸出數(shù)據(jù)的首地址焰情;
  2. size 表示數(shù)據(jù)塊的字節(jié)數(shù);
  3. count 表示要讀寫的數(shù)據(jù)塊的塊數(shù)
  4. fp 表示文件的指針
//案例7:
#include<stdio.h>
struct student
{
    int id;
    char name[20];
    float score;
};

int main()
{
    struct student boy[2];
    int i = 0;
    for (;i < 2; i++)
    {
      printf("input the student's infomation(id, name, score):");
      scanf("%d%s%f",&boy[i]->id,boy[i]->name,&boy[i]->score);
    }
    
    FILE* fp;
    fp = fopen("./student.text","w+");
    if (NULL == fp)
    {
      printf("open file error\n");
      exit(1);
    }
    
    fwrite(boy,sizeof(struct student),2,fp);
    rewind(fp);
    struct student stu[2];
    fread(stu,sizeof(struct student),2,fp);
    printf("id\tname\tscore\n");
    for (i = 0; i < 2; i++)
    {
      printf("%d\t%s\t%f\n",stu[i]->id,stu[i]->name,stu[i]->score);
    }
    return 0;
}

4. 格式化讀寫函數(shù)fscanf 和 fprintf

fscanf剥懒、fprintf和scanf内舟、printf的區(qū)別:
fscanf和fprintf函數(shù)的讀寫不是對鍵盤和顯示器的,而是對磁盤文件初橘;不過它們都是格式化讀寫函數(shù)验游。

fscanf 的一般形式:
fscanf(文件指針, 格式字符串保檐, 輸入列表)耕蝉;
fprintf 的一般形式:
fprintf(文件指針, 格式字符串夜只, 輸出列表)垒在;

//案例8:
#include<stdio.h>
int main()
{
    char caBuf[3][32] = {'\0'};
    int i = 0;
    
    for (; i < 3; i++)
    {
      printf("input :");
      scanf("%s", caBuf[i]);
    }
    
    FILE *fp;
    fp = fopen("./MyInput", "wb+");
    if (NULL == fp)
    {
      printf("open file error\n");
      exit(1);
    }
    for (i=0; i < 3; i++)
    {
      fprintf(fp, "%s", caBuf[i]);
    }
    rewind(fp);
    char sMsg[32] = {'\0'};
    for(i=0; i < 3; i++)
    {
      fscanf(fp, "%s", sMsg);
      printf("sMsg: %s\n", sMsg);
    }
    fclose(fp);
    return 0;
}

文件定位

有的時候我們在讀寫文件時,不想從開頭或者末尾開始讀或者寫扔亥;想讀取中間的內(nèi)容场躯,或者是想將一段數(shù)據(jù)插入到文件中間,我們該怎么做旅挤?這時候踢关,我們就需要引入新的知識,文件的定位粘茄。

文件定位函數(shù)

在文件定位中签舞,主要有兩個函數(shù):rewind()和fseek().
rewind() 在前面已經(jīng)使用,并進行一定的說明柒瓣,不過在這里還是要重申一下儒搭,其一般形式為:
rewind(文件指針);

功能:文件內(nèi)部的文件指針轉(zhuǎn)移到文件首部嘹朗。

fseek() 的一般形式:
fseek(文件指針师妙, 位移量, 起始點);

參數(shù)說明:
文件指針:被指向移動的文件屹培;
位移量:表示移動的字節(jié)數(shù)默穴;
起始點:表示從何處開始計算位移量怔檩,規(guī)定有三種:文件首部(SEEK_SET,1)蓄诽,當(dāng)前位置(SEEK_CUR薛训,0)和文件尾部(SEEK_END, 2)仑氛。

// 案例10:
fseek(fp, 100, 0);
//表示:把文件位置指針移到距離首部100個字節(jié)處乙埃。

注意事項:fseek()一般用于二進制文件。在文本文件中由于要進行轉(zhuǎn)換锯岖,故往往計算位置會出現(xiàn)錯誤

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末介袜,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子出吹,更是在濱河造成了極大的恐慌遇伞,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,743評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件捶牢,死亡現(xiàn)場離奇詭異鸠珠,居然都是意外死亡,警方通過查閱死者的電腦和手機秋麸,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,296評論 3 385
  • 文/潘曉璐 我一進店門渐排,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人灸蟆,你說我怎么就攤上這事驯耻。” “怎么了次乓?”我有些...
    開封第一講書人閱讀 157,285評論 0 348
  • 文/不壞的土叔 我叫張陵吓歇,是天一觀的道長。 經(jīng)常有香客問我票腰,道長城看,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,485評論 1 283
  • 正文 為了忘掉前任杏慰,我火速辦了婚禮测柠,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘缘滥。我一直安慰自己轰胁,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 65,581評論 6 386
  • 文/花漫 我一把揭開白布朝扼。 她就那樣靜靜地躺著赃阀,像睡著了一般。 火紅的嫁衣襯著肌膚如雪擎颖。 梳的紋絲不亂的頭發(fā)上榛斯,一...
    開封第一講書人閱讀 49,821評論 1 290
  • 那天观游,我揣著相機與錄音,去河邊找鬼驮俗。 笑死懂缕,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的王凑。 我是一名探鬼主播搪柑,決...
    沈念sama閱讀 38,960評論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼索烹!你這毒婦竟也來了工碾?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,719評論 0 266
  • 序言:老撾萬榮一對情侶失蹤术荤,失蹤者是張志新(化名)和其女友劉穎倚喂,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體瓣戚,經(jīng)...
    沈念sama閱讀 44,186評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,516評論 2 327
  • 正文 我和宋清朗相戀三年焦读,在試婚紗的時候發(fā)現(xiàn)自己被綠了子库。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,650評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡矗晃,死狀恐怖仑嗅,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情张症,我是刑警寧澤仓技,帶...
    沈念sama閱讀 34,329評論 4 330
  • 正文 年R本政府宣布,位于F島的核電站俗他,受9級特大地震影響脖捻,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜兆衅,卻給世界環(huán)境...
    茶點故事閱讀 39,936評論 3 313
  • 文/蒙蒙 一地沮、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧羡亩,春花似錦摩疑、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,757評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至辞居,卻和暖如春楷怒,著一層夾襖步出監(jiān)牢的瞬間寨腔,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,991評論 1 266
  • 我被黑心中介騙來泰國打工率寡, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留迫卢,地道東北人。 一個月前我還...
    沈念sama閱讀 46,370評論 2 360
  • 正文 我出身青樓冶共,卻偏偏與公主長得像乾蛤,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子捅僵,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,527評論 2 349

推薦閱讀更多精彩內(nèi)容

  • [TOC] UNIX的哲學(xué),萬物皆文件. 打開關(guān)閉文件 FILE * fopen(const char *file...
    robinguo2012閱讀 720評論 0 0
  • 文件指針 FILE * 指針變量標(biāo)識符作用:通過該指針即可找到存放某個文件信息的結(jié)構(gòu)變量家卖,然后按結(jié)構(gòu)變量提供的信息...
    永斷閻羅閱讀 457評論 0 3
  • 語言中對文件進行操作必須首先打開文件,打開文件主要涉及到fopen函數(shù)庙楚。fopen函數(shù)的原型為 FILE* fop...
    朱森閱讀 797評論 0 1
  • 文件操作是實際應(yīng)用的重要部分上荡,本文基于C程序設(shè)計(譚浩強版)所寫。 C語言文件讀寫 fopen馒闷,fclose(打開...
    靜候那一米陽光閱讀 374評論 0 0
  • 或許再過幾個年頭,我們都會分開疏虫,可是終歸我們曾經(jīng)相遇過永罚,我對你最大的期望便是健康就好! 很多時候卧秘,我們覺得我們是主...
    失憶路人甲yu閱讀 294評論 0 0