C語(yǔ)言文件讀寫

文件操作是實(shí)際應(yīng)用的重要部分,本文基于C程序設(shè)計(jì)(譚浩強(qiáng)版)所寫。

C語(yǔ)言文件讀寫

fopen,fclose(打開關(guān)閉文件)

FILE *文件指針;// FILE *fp;
fopen(文件名,使用文件方式);//fp = fopen("file","r");
fclose(文件指針);//close(fp);

如果不能打開文件,fopen函數(shù)返回空指針值NULL。可能原因:文件不存在,磁盤故障,磁盤已滿等。

fclose成功執(zhí)行返回0,否則返回EOF(-1)。

文件使用方式 含義 如果文件不存在
r(只讀) 輸入,打開文本文件 出錯(cuò)
w(只寫) 輸出,打開文本文件 建立新文件
a(追加) 向文本文件尾添加數(shù)據(jù) 出錯(cuò)
rb(只讀) 輸入,打開二進(jìn)制文件 出錯(cuò)
wb(只寫) 輸出,打開二進(jìn)制文件 建立新文件
ab(追加) 向二進(jìn)制文件尾添加數(shù)據(jù) 出錯(cuò)
r+(讀寫) 讀寫,打開文本文件 出錯(cuò)
w+(讀寫) 讀寫,建立新的文本文件 建立新文件
a+(讀寫) 讀寫,打開文本文件 出錯(cuò)
rb+(讀寫) 讀寫,打開二進(jìn)制文件 出錯(cuò)
wb+(讀寫) 讀寫,建立新的二進(jìn)制文件 建立新文件
ab+(讀寫) 讀寫,打開二進(jìn)制文件 出錯(cuò)

示例:

File *fp;

//打開
if((fp = fopen("D:\\fp.txt","r"))==NULL)
{
    printf("文件打開失敗!");
    exit(0);
}

//關(guān)閉
fclose(fp);

順序讀寫文件

fgetc,fputc(讀寫字符)

int fgetc(FILE *stream);//fgetc(fp);
int fputc (char c, File *fp);//fputc("hello",fp);

讀寫成功,返回所讀寫的字符的ASCII碼的十進(jìn)制值。失敗返回EOF(-1)。

返回值是int型,所以應(yīng)該用int ch; ch = fget(fp);接受讀取到的字符。

fgetc()與getc()/fputc()與putc()作用一樣。
示例:

while(!feof(fp))
{
    ch = fgetc(fp);
    fputc(ch,fp2);
}

fgets,fputs(讀寫字符串)

char *fgets(char *str, int n, FILE *fp);
int fputs(char *str,FILE *fp);

*str:字符型指針,指向用來存儲(chǔ)所得數(shù)據(jù)的地址。

n:整型數(shù)據(jù),指明存儲(chǔ)數(shù)據(jù)的大小。

*fp:文件結(jié)構(gòu)體指針,將要讀取/寫入的文件流。

fgets成功:返回str數(shù)組首元素的地址;失敗:一開始就遇到文件尾或者讀數(shù)據(jù)出錯(cuò),返回NULL。
fputs成功:返回0;失敗:返回非0值。

fgets實(shí)際上讀入n-1個(gè)字符,然后在最后加一個(gè)'\0',這樣一共是n個(gè)字符,把它們放到字符數(shù)組str中。如果在讀完n-1個(gè)字符前遇到'\n'或者文件結(jié)束符EOF,讀入結(jié)束,但是'\n'也作為一個(gè)字符讀入

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

fgets、fputs類似于gets、puts,但是后者以終端為讀寫對(duì)象,前者以特定的文件為讀寫對(duì)象。

示例:

FILE *f1,*f2;
char str[10][10];
int i = 0;
if((f1=fopen("D:\\in.txt","r")) == NULL)
{
    printf("can not open the file!");
}
if((f2=fopen("D:\\out.txt","w+")) == NULL)
{
    printf("can not open the file!");
}
while(fgets(str[i],10,f1) != NULL)
{
    //printf("%d,%s\n",i,str[i]);
    fprintf(f2,"%s",str[i]);
    i++;
}
fclose(f1);
fclose(f2);

fscanf,fprintf(格式化讀寫文件)

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

示例:

fscanf(fp,"%d,%f",&i,&f);
fprintf(fp,"%d,%6.2f",i,f);

類似于scanf,printf。

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

fread,fwrite(用二進(jìn)制方式讀寫)

fread(buffer,size,count,fp);
fwrite(buffer,size,count,fp);

buffer:地址。對(duì)于fread,是存放從文件讀入數(shù)據(jù)的存儲(chǔ)區(qū)的地址;對(duì)于fwrite,是要把此地址開始的存儲(chǔ)區(qū)中的數(shù)據(jù)向文件輸出。均為起始地址。
size:要讀寫的字節(jié)數(shù)。

count:要讀寫多少個(gè)數(shù)據(jù)項(xiàng)(每個(gè)數(shù)據(jù)項(xiàng)長(zhǎng)度為size)。

fp:FILE類型指針。

fread,fwrite函數(shù)的類型為int型,如果函數(shù)執(zhí)行成功,則返回形參count的值,即輸入或輸出數(shù)據(jù)項(xiàng)的個(gè)數(shù)。

示例:

fread(f,4,10,fp);
其中f是一個(gè)float型數(shù)組名(數(shù)組首元素地址)。從fp所指向的文件讀入4個(gè)字節(jié)的數(shù)據(jù),存儲(chǔ)到數(shù)組f中。

struct Student_type
{
    char name[10];
    int num;
    int age;
    char addr[30];
}stud[40];
for (i=0;i<40;i++)
{
    //每次從fp指向的文件讀入結(jié)構(gòu)體數(shù)組stu的一個(gè)元素
    fread(&stud[i],sizeof(struct Student_type),1,fp);
    //講內(nèi)存中的學(xué)生數(shù)據(jù)寫入到磁盤文件中去
    fwrite(&stud[i],sizeof(struct Student_type),1,fp2);
}

//實(shí)例:向文件中寫入若干結(jié)構(gòu)體數(shù)據(jù)并進(jìn)行讀取。=
#include <iostream>
#include <stdlib.h>
#define SIZE 1
struct Student_type
{
    char name[10];
    int num;
    int age;
    char addr[15];
}stud[SIZE];

void save()
{
    FILE *fp;
    int i;
    if((fp=fopen("D:\\stu","wb"))==NULL)
    {
        printf("err");
        exit(0);
    }
    for(i=0;i<SIZE;i++)
        if (fwrite(&stud[i],sizeof(struct Student_type),1,fp)!=1)
        {
            printf("error");
        }
    fclose(fp);
}

void read()
{
    FILE *fp;
    int i;
    if((fp=fopen("D:\\stu","rb"))==NULL)
    {
        printf("err");
        exit(0);
    }
    for(i=0;i<SIZE;i++)
    {
        if(fread(&stud[i],sizeof(struct Student_type),1,fp)!=1)
        {
            printf("error");
        };
        printf("%-10s %4d %4d %-15s\n",stud[i].name,stud[i].num,stud[i].age,stud[i].addr);
    }
    fclose(fp);
}

int main()
{
    int i;
    printf("請(qǐng)輸入10組學(xué)生數(shù)據(jù):\n");
        for (i=0;i<SIZE;i++)
        {
            scanf("%s%d%d%s",stud[i].name,&stud[i].num,&stud[i].age,stud[i].addr);
        }
    save();
    read();
    system("pause");
    return 0;
}

隨機(jī)讀寫文件

rewind

rewind(fp);

使文件位置標(biāo)記指向文件開頭。函數(shù)沒有返回值。

fseek

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

起始點(diǎn):用0,1,2代替。0(SEEK_SET):文件開始位置;1(SEEK_CUR):當(dāng)前位置;2(SEEK_END):文件末尾位置。

位移量:以“起始點(diǎn)”為幾點(diǎn),向前移動(dòng)的字節(jié)數(shù)。位移量應(yīng)是long型數(shù)據(jù)(在數(shù)字的末尾加一個(gè)字母L,就表示是long型)。

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

示例:

fseek(fp,100L,0);//將文件位置標(biāo)記向前移到離文件開頭100個(gè)字節(jié)處。
fseek(fp,50L,1);//將文件位置標(biāo)記向前移到離當(dāng)前位置50個(gè)字節(jié)處。
fseek(fp,-10L,2);//將文件位置標(biāo)記從文件末尾處向后退10個(gè)字節(jié)。

ftell

ftell(fp);

測(cè)定文件位置標(biāo)記的當(dāng)前位置。用相對(duì)于文件開頭的位移量來表示。
如果調(diào)用函數(shù)時(shí)出錯(cuò),ftell函數(shù)返回值為-1L。

示例:

i = ftell(fp);
if(i==-1L)
{
    printf("error");
}

出錯(cuò)檢測(cè)

ferror

ferror(fp);

調(diào)用輸入輸出函數(shù)(fputc,fgetc,fread,fwrite等)時(shí),如果出現(xiàn)錯(cuò)誤,除了函數(shù)返回值有所反映,還可以用ferror檢查。

未出錯(cuò):返回值為0;出錯(cuò):返回非零值。執(zhí)行fopen時(shí),ferror自動(dòng)置0。

clearerr

clearerr(fp);

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

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,622評(píng)論 6 544
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 99,716評(píng)論 3 429
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,746評(píng)論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我,道長(zhǎng),這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,991評(píng)論 1 318
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 72,706評(píng)論 6 413
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 56,036評(píng)論 1 329
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 44,029評(píng)論 3 450
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 43,203評(píng)論 0 290
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 49,725評(píng)論 1 336
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 41,451評(píng)論 3 361
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 43,677評(píng)論 1 374
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,161評(píng)論 5 365
  • 正文 年R本政府宣布,位于F島的核電站,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 44,857評(píng)論 3 351
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,266評(píng)論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,606評(píng)論 1 295
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 52,407評(píng)論 3 400
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 48,643評(píng)論 2 380

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