溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

C語(yǔ)言中怎么實(shí)現(xiàn)文件操作

發(fā)布時(shí)間:2021-10-18 09:17:35 來(lái)源:億速云 閱讀:101 作者:柒染 欄目:開(kāi)發(fā)技術(shù)

本篇文章給大家分享的是有關(guān)C語(yǔ)言中怎么實(shí)現(xiàn)文件操作,小編覺(jué)得挺實(shí)用的,因此分享給大家學(xué)習(xí),希望大家閱讀完這篇文章后可以有所收獲,話不多說(shuō),跟著小編一起來(lái)看看吧。

    什么是文件

    磁盤(pán)上的文件是文件

    但是在程序設(shè)計(jì)中,我們一般談的文件有兩種:程序文件和數(shù)據(jù)文件(從文件功能的角度來(lái)分類)。

    程序文件

    包括源程序文件(例如.c文件)目標(biāo)文件(windows環(huán)境后綴為.obj)可執(zhí)行程序(windos環(huán)境后綴為exe)。

    數(shù)據(jù)文件 (本文重點(diǎn))

    文件的內(nèi)容不一定是程序,而是程序運(yùn)行時(shí)讀寫(xiě)的數(shù)據(jù),比如程序運(yùn)行需要從中讀取數(shù)據(jù)的文件,或者輸出內(nèi)容的文件。

    文件名

    文件就像人一樣,他也要有姓氏和名字來(lái)讓其他文件或者人知道這個(gè)文件是誰(shuí)。

    對(duì)于每一個(gè)文件要,,都有一個(gè)唯一的文件標(biāo)識(shí),以便用戶識(shí)別和引用。

    文件名格式:文件路徑+文件名主干+文件后綴

    例如:D:\CSDN\Test.txt

    為了方便起見(jiàn),我們叫文件標(biāo)識(shí)為文件名

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

    文件指針

    我們知道,指針是指向一個(gè)地址的,整形指針指向一個(gè)整形的空間,數(shù)組指針指向一個(gè)數(shù)組的空間,那么文件指針自然就是指向文件的指針了。

    每個(gè)被使用的文件都在內(nèi)存中開(kāi)辟了一個(gè)相應(yīng)的文件信息區(qū),用來(lái)存放文件的相關(guān)信息(如文件的名字,文件狀態(tài)及文件當(dāng)前的位置等)。這些信息是保存在一個(gè)結(jié)構(gòu)體變量中的。該結(jié)構(gòu)體類型是有系統(tǒng)聲明的,取名FILE。

    這是再vs的stdio頭文件下的文件信息區(qū)結(jié)構(gòu)體

    struct _iobuf {
            char *_ptr;
            int   _cnt;
            char *_base;
            int   _flag;
            int   _file;
            int   _charbuf;
            int   _bufsiz;
            char *_tmpfname;
            };
    typedef struct _iobuf FILE;
    //不同的C編譯器的FILE類型包含的內(nèi)容不完全相同,但是大同小異。

    就像學(xué)生要有學(xué)號(hào)姓名年齡這些信息一樣,文件也有他的信息,比如這個(gè)文件的地址。這些信息存放于這個(gè)結(jié)構(gòu)體中,通過(guò)typedef重命名為FILE,并且我們不需要關(guān)心一些細(xì)節(jié)(你會(huì)關(guān)心我昨天晚上吃了什么嗎)。

    一般都是通過(guò)一個(gè)FILE的指針來(lái)維護(hù)這個(gè)FILE結(jié)構(gòu)的變量,這樣使用起來(lái)更加方便。

    下面我們可以創(chuàng)建一個(gè)FILE*的指針變量:

    FILE* pf;

    pf通過(guò)該文件信息區(qū)中的信息就能夠訪問(wèn)該文件。

    也就是說(shuō),通過(guò)文件指針變量能夠找到與它關(guān)聯(lián)的文件。

    但上面的文件指針并未指向明確的位置,他暫時(shí)是一個(gè)野指針

    所以接下來(lái),我們來(lái)學(xué)習(xí)如何打開(kāi)(創(chuàng)建)一個(gè)文件。

    文件函數(shù)

    文件在讀寫(xiě)之前應(yīng)該先打開(kāi)文件,在使用結(jié)束之后應(yīng)該關(guān)閉文件。

    在編寫(xiě)程序的時(shí)候,在打開(kāi)文件的同時(shí),都會(huì)返回一個(gè)FILE*的指針變量指向該文件,也相當(dāng)于建立了指針和文件的關(guān)系。

    ANSIC規(guī)定使用fopen函數(shù)來(lái)打開(kāi)文件,fclose來(lái)關(guān)閉文件。

    //打開(kāi)文件
    FILE* fopen(const char *filename,const char *mode);
    //第一個(gè)參數(shù)是文件名,第二個(gè)參數(shù)是打開(kāi)方式
    //關(guān)閉文件
    int Fclose(FILE *stream);

    部分打開(kāi)方式如下圖

    C語(yǔ)言中怎么實(shí)現(xiàn)文件操作

    現(xiàn)在我們來(lái)練習(xí)一下打開(kāi)文件

    //打開(kāi)文件
    	FILE* pf = fopen("data.txt","r");
    	//以只讀的方式打開(kāi)這個(gè)文件
    	//如果文件打開(kāi)失敗會(huì)返回空,否則會(huì)返回指向該文件的指針
    	if (pf == NULL){
    		perror("fopen");
    		return -1;
    	}
    	//讀文件
    	//關(guān)閉文件
    	fclose(pf);
    	pf = NULL;
    	return 0;

    C語(yǔ)言中怎么實(shí)現(xiàn)文件操作

    但是卻打開(kāi)失敗了!!

    原因是,從上面的打開(kāi)方式一圖我們可以看出,以"r"方式打開(kāi),需要該文件真實(shí)存在,但是我并沒(méi)有創(chuàng)建這個(gè)文件,所以打開(kāi)失敗了

    叮~文件創(chuàng)建成功

    我們?cè)賮?lái)看執(zhí)行結(jié)果

    C語(yǔ)言中怎么實(shí)現(xiàn)文件操作

    這回沒(méi)有報(bào)錯(cuò)

    但是,這里是將data.txt文件放在了該.c文件目錄下,在我將該文件放在別的地方,仍然打開(kāi)失敗報(bào)錯(cuò)。

    原因是,我們這段代碼只輸入了文件名,所以他只在當(dāng)前文件目錄下尋找該文件,在其他地方的文件我們就找不到了。

    這里我們來(lái)看看兩個(gè)東西,一個(gè)叫相對(duì)路徑,一個(gè)叫絕對(duì)路徑

    相對(duì)路徑與絕對(duì)路徑

     相對(duì)路徑

    只認(rèn)為是當(dāng)前目錄下的文件,如上面的代碼中。

    絕對(duì)路徑

    帶上文件的從磁盤(pán)到目標(biāo)文件的路徑

    例如

    D:\Program Files\data.txt

    但是請(qǐng)注意,在編程中,\是轉(zhuǎn)義字符,所以我們需要讓\不再是轉(zhuǎn)義字符,使其代表它本身

    D:\Program Files\data.txt

    輸入輸出流

    什么是輸入輸出流

    學(xué)習(xí)過(guò)編程,一定知道printf或者cout或者System.out.println吧,

    這些函數(shù)用于打印數(shù)據(jù),這就是標(biāo)準(zhǔn)的輸出流。使數(shù)據(jù)輸出或者寫(xiě)入文件中,我們叫輸出流。

    我們打印HELLO WORLD在屏幕上,就是一個(gè)標(biāo)準(zhǔn)輸出流

    像scanf之類的,從文件輸入或者讀數(shù)據(jù)到內(nèi)存中,就是輸入流。

    一些基本的輸入輸出函數(shù)如下。

    C語(yǔ)言中怎么實(shí)現(xiàn)文件操作

    比如,fputc就是寫(xiě)一個(gè)字符進(jìn)去,fgetc就是讀一個(gè)字符。

    //打開(kāi)文件
    	FILE* pf = fopen("data.txt","w");
    	if (pf == NULL){
    		perror("fopen");
    		return -1;
    	}
    	//讀文件
    	fputc('a', pf);
    	fputc('b', pf);
    	fputc('c', pf);
    	//fputc第一個(gè)參數(shù)為輸入的字符,第二個(gè)使對(duì)應(yīng)文件的指針
    
    	//關(guān)閉文件
    	fclose(pf);
    	pf = NULL;
    	return 0;

    C語(yǔ)言中怎么實(shí)現(xiàn)文件操作

    寫(xiě)入了abc三個(gè)字符。

    fputc和fgetc每次讀/寫(xiě)一個(gè)字符后,文件指針pf會(huì)向后移動(dòng),類似strtok函數(shù)。會(huì)記錄上一次輸入/輸出的地址。

    如果不這樣,那豈不是一直在一個(gè)位置重復(fù)寫(xiě)入或者讀文件了。

    接下來(lái)看看fgetc讀取字符

    //打開(kāi)文件
    	FILE* pf = fopen("data.txt","r");
    	if (pf == NULL){
    		perror("fopen");
    		return -1;
    	}
    	//讀文件
    
    	int a = fgetc(pf);
    	printf("%c", a);
    	a = fgetc(pf);
    	printf("%c", a);
    	a = fgetc(pf);
    	printf("%c",a);
    	//關(guān)閉文件
    	fclose(pf);
    	pf = NULL;
    	return 0;

    執(zhí)行結(jié)果

    C語(yǔ)言中怎么實(shí)現(xiàn)文件操作

    這就是順序讀寫(xiě),按著順序讀入寫(xiě)入。

    當(dāng)然,有順序讀寫(xiě),就會(huì)有隨機(jī)讀寫(xiě)

    從字面意思就能看到,隨機(jī)讀寫(xiě)emmm。

    當(dāng)然,除了fgetc這類,fgets自然就是讀取一行了(只會(huì)讀/寫(xiě)一行哦)

    如果你用這類函數(shù)輸出在標(biāo)準(zhǔn)輸入或者標(biāo)準(zhǔn)輸入(stdout或者stdin)上,他和printf,scanf沒(méi)什么區(qū)別。

    接下來(lái),我們來(lái)看二進(jìn)制的讀和寫(xiě)

    二進(jìn)制讀寫(xiě)

    fwirte

    C語(yǔ)言中怎么實(shí)現(xiàn)文件操作

    以二進(jìn)制的形式將內(nèi)容寫(xiě)入文件中

    第一個(gè)參數(shù)是你要寫(xiě)入數(shù)據(jù)的數(shù)據(jù)地址,第二個(gè)參數(shù)是一個(gè)類型的大?。ㄗ止?jié))。第三個(gè)參數(shù)是你要寫(xiě)入幾個(gè)數(shù)據(jù),第四個(gè)則是你選定寫(xiě)入的流。

    struct S{
    	int n;
    	double d;
    	char name[10];
    };
    
    int main()
    {
    	struct S s = { 10, 3.14, "zhangsan" };
    	//打開(kāi)文件
    	FILE* pf = fopen("data.txt","wb");
    	if (pf == NULL){
    		perror("fopen");
    		return -1;
    	}
    	//讀文件
    	fwrite(&s,sizeof(s),1,pf);
    
    	//關(guān)閉文件
    	fclose(pf);
    	pf = NULL;
    	return 0;
    }

    如上代碼會(huì)將數(shù)據(jù)以二進(jìn)制的形式寫(xiě)入data.txt

    雖然我們看不懂,但是能看到zhangsan是我們輸入的內(nèi)容

    C語(yǔ)言中怎么實(shí)現(xiàn)文件操作

    fread

    以二進(jìn)制的形式讀

    C語(yǔ)言中怎么實(shí)現(xiàn)文件操作

    和fwirte一樣,只不過(guò)buffer不是const形式了,因?yàn)槲覀円獙?shù)據(jù)讀入該指針指向的目標(biāo)。

    struct S{
    	int n;
    	double d;
    	char name[10];
    };
    
    int main()
    {
    	struct S s = {0};
    	//打開(kāi)文件
    	FILE* pf = fopen("data.txt","rb");
    	if (pf == NULL){
    		perror("fopen");
    		return -1;
    	}
    	//讀文件
    	fread(&s,sizeof(struct S),1,pf);
    	printf("%d  %lf  %s\n",s.n,s.d,s.name);
    
    	//關(guān)閉文件
    	fclose(pf);
    	pf = NULL;
    	return 0;
    }

    C語(yǔ)言中怎么實(shí)現(xiàn)文件操作

    以上就是C語(yǔ)言中怎么實(shí)現(xiàn)文件操作,小編相信有部分知識(shí)點(diǎn)可能是我們?nèi)粘9ぷ鲿?huì)見(jiàn)到或用到的。希望你能通過(guò)這篇文章學(xué)到更多知識(shí)。更多詳情敬請(qǐng)關(guān)注億速云行業(yè)資訊頻道。

    向AI問(wèn)一下細(xì)節(jié)

    免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

    AI