文件
1.文件:存儲(chǔ)在外部介質(zhì)上數(shù)據(jù)的集合
2.文件是有序的數(shù)據(jù)序列,要訪問(wèn)文件中的數(shù)據(jù),必須按照它們的排列順序,依次訪問(wèn)
3.系統(tǒng)對(duì)文件的處理過(guò)程:
讀(輸入):計(jì)算機(jī)外存--->緩沖區(qū)--->計(jì)算機(jī)內(nèi)存
寫(xiě)(輸出):計(jì)算機(jī)內(nèi)存--->緩沖區(qū)---->計(jì)算機(jī)外存
4.文件的分類(lèi):
①根據(jù)在磁盤(pán)的存儲(chǔ)格式,分為:
文本文件(TXT/ASCⅡ文件):
? ? ?文本文中保存的數(shù)據(jù)用ASCⅡ作為存儲(chǔ)方式,先將全部數(shù)據(jù)轉(zhuǎn)換為ASCⅡ碼形式,每個(gè)ASCⅡ碼占一個(gè)字節(jié)
? ? ?文本文件使用編輯軟件可以直接閱讀
二進(jìn)制文件:
? ? ? 將數(shù)據(jù)在內(nèi)存中以二進(jìn)制格式存儲(chǔ),直接存入文件中
? ? ? 二進(jìn)制文件使用編輯器軟件不能直接閱讀
②從用戶(hù)觀點(diǎn),分為:
普通文件(磁盤(pán)文件):
? ? ? ?以磁盤(pán)為對(duì)象,無(wú)其他特殊性能
特殊文件(標(biāo)準(zhǔn)設(shè)備文件/標(biāo)準(zhǔn)I/0文件):
? ? ? ?以終端為對(duì)象標(biāo)準(zhǔn)設(shè)備文件;
? ? ? ?邏輯文件(設(shè)備文件):與主機(jī)進(jìn)行設(shè)備交換的輸入輸出設(shè)備(即實(shí)際的物理設(shè)備)
? ? ? ? ? ? 例如:鍵盤(pán)作為標(biāo)準(zhǔn)輸入文件:文件名stdin,
? ? ? ? ? ? ? ? ? 顯示器作為標(biāo)準(zhǔn)輸出文件:文件名stdout,
? ? ? ? ? ? ? ? ? 打印機(jī)作為輸入文件:文件名PRN
③從c語(yǔ)言對(duì)文件的處理方式看,分為:
緩沖文件:?
? ? 對(duì)每個(gè)正在使用的文件,系統(tǒng)自動(dòng)在內(nèi)存中為其開(kāi)辟一個(gè)文件緩沖區(qū)(即高級(jí)文件操作)
非緩沖文件:
? ? 系統(tǒng)不自動(dòng)開(kāi)辟文件緩沖區(qū),由應(yīng)用程序自己設(shè)置(即低級(jí)文件操作)
一、文件的處理:
1.文件類(lèi)型結(jié)構(gòu):
FILE類(lèi)型,包括在頭文件stdio.h
文件結(jié)構(gòu):
typedef struct {short level;//文件緩沖區(qū)剩余的字節(jié)數(shù)unsigned flags;//文件狀態(tài)標(biāo)志char fd;//文件描述符unsigned char hold;//緩沖區(qū)滿(mǎn)丟失的字符short bsize; //文件緩沖區(qū)大小unsigned char *buffer;//文件緩沖區(qū)地址unsigned char *curp;//指針指向當(dāng)前文件的讀寫(xiě)位置unsigned istemp;//臨時(shí)文件,指示器short token;//用于有效性檢查 }FILE;2.文件指針變量: ?預(yù)包含stdio.h 頭文件,形式 ?FILE *文件型指針變量名
例如:FILE *fp;
fp是一個(gè)指針變量指向文件結(jié)構(gòu),要同時(shí)使用多個(gè)文件,必須有多個(gè)不同的文件指針。
3.c語(yǔ)言中提供了三個(gè)標(biāo)準(zhǔn)文件的指針: 標(biāo)準(zhǔn)輸入文件(鍵盤(pán)):stdin,
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 標(biāo)準(zhǔn)輸出文件(顯示器):stdout,
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 標(biāo)準(zhǔn)錯(cuò)誤輸出文件(顯示器):stderr
二、文件的操作流程
- 第一步:打開(kāi)(新建)文件(fopen)
- 第二步:對(duì)文件進(jìn)行操作(讀或?qū)?#xff09;
- 第三步:關(guān)閉文件(fclose)
1.打開(kāi)文件
fopen函數(shù)
函數(shù)原型:
- FILE *fopen(charc *filename,char *mode);
//使用mode模式打開(kāi)指定的filename文件
//文件打開(kāi)成功,返回值為FILE類(lèi)型的指針
//文件打開(kāi)失敗,返回NULL
調(diào)用形式:
fp=fopen (文件名,文件使用方式);
文件名:需要打開(kāi)的文件名稱(chēng)(字符串)
例如:
fp=fopen(“e:\\code\\test.txt”,”rt”);//以只讀方式打開(kāi)路徑為e:/code/est.txt的文件
fp=fopen(“e:/code/test.txt”,”wt”);//以只寫(xiě)方式打開(kāi)路徑e:/code/test.txt文件 ? ? ?
fp=fopen("text.txt","r");//只讀的方式打開(kāi)一個(gè)和可執(zhí)行文件在相同路徑下的文本文件test.txt
文件使用方式;
"r":讀,為讀方式(輸入)打開(kāi)文件,該文件必須存在,若文件不存在,則返回NULL
"w":寫(xiě)(輸出)方式打開(kāi)文本文件,若文件不存在,則建立一個(gè)新文件,若文件已存在,則將原來(lái)的文件清空
"a":追加,在文本文件的末尾增加數(shù)據(jù),若文件存在,則保持原來(lái)文件的內(nèi)容,將新的數(shù)據(jù)增加到原來(lái)的后面;若文件不存在,則返回NULL;
"t":文本文件
"b":二進(jìn)制文件
"+":讀和寫(xiě)
文件的其他打開(kāi)方式:
"r+":對(duì)文本文件進(jìn)行讀/寫(xiě)文件不存在返回NULL,若文件存在內(nèi)容不會(huì)被清空
"w+":可以文本文件進(jìn)行讀/寫(xiě)操作,若文件已存在,則將文件原來(lái)的內(nèi)容清空
"a+":文本文件進(jìn)行讀/追加操作,文件內(nèi)容不會(huì)清空
"rb+":對(duì)二進(jìn)制文件進(jìn)行讀/寫(xiě)操作
"wb+":對(duì)二進(jìn)制文件進(jìn)行讀/寫(xiě)操作
"ab+":對(duì)二進(jìn)制文件進(jìn)行讀/追加操作
常見(jiàn)文件打開(kāi)操作:
if((fp=fopen("d:\\file.txt","r"))==NULL) {printf("cannot open file.\n");exit(0); }//以只讀方式打開(kāi)D盤(pán)根目錄下“file.txt”文件,
//文件打開(kāi)成功,將為該文件的結(jié)構(gòu)的地址返回存入fp
//如果打開(kāi)文件失敗,fopen函數(shù)返回一個(gè)空指針,exit( ); 函數(shù):0表示程序正常退出,1表示錯(cuò)誤退出
2.關(guān)閉文件:
fclose函數(shù):
原型:int fclose (FILE *fp);
調(diào)用格式: fclose(fp);
fp:已經(jīng)打開(kāi)的文件指針
函數(shù)功能:關(guān)閉fp指定的文件,切斷緩沖區(qū)與該文件的聯(lián)系,并釋放文件指針
? ? ? ? ? 若文件關(guān)閉成功,返回值0,關(guān)閉失敗,返回非0值
三、文件的順序讀寫(xiě):
對(duì)文件的操作必須按照文件中字符的先后順序進(jìn)行,從頭到尾主數(shù)據(jù)讀入或?qū)懗觥?/span>
字符串輸入輸出函數(shù) ? ? fgetc ?fputc
字符串輸入輸出函數(shù) ? ? fgets ?fputs
格式化輸入輸出函數(shù) ? ? fscanf ?fprintf
數(shù)據(jù)塊輸入輸出函數(shù) ? ? fread ? fwrite
1.單字符讀寫(xiě)函數(shù):
- 讀:int fgetc(FILE *fp);
- 寫(xiě):int fputc(char ch,FILE *fp
調(diào)用形式:
?輸入函數(shù):ch=fgetc(fp);
//從指定文件中讀取一個(gè)字符,讀取的字符付給變量ch
//對(duì)于ASCⅡ文件,若讀取字符時(shí)文件已經(jīng)結(jié)束或出錯(cuò),返回EOF(-1)
? 輸出函數(shù):fputc(ch,fp);
//將一個(gè)字符輸出到指定文件中,即將字符變量ch中的字符輸出到fp所指向的文件
//輸出操作成功,則函數(shù)返回輸出的字符,否則返回EOF
2.字符串讀寫(xiě)函數(shù)
- 讀:char *fgets(char *str,int n,FILE *fp);
- 寫(xiě):int fputs(char *str,FILE *fp);?
輸入函數(shù):fgets(s,n,fp);//其中參數(shù):char s[ ]; int n; FIFLE *fp;
//從fp所指向的文件中讀取長(zhǎng)度不超過(guò)n-1個(gè)字符串(串尾為\0),并將該字符串放到字符數(shù)組s中,
//函數(shù)的返回值為字符數(shù)組s的首地址;文件出錯(cuò)或結(jié)束,返回NULL;
//若:已讀入n-1個(gè)字符,串尾為\0 ?則:s中存入n-1個(gè)字符,串尾為\0
? ? ? 讀入字符遇\0 ? 則:s中存入實(shí)際讀入的字符,串尾\0
? ? ? 讀入字符遇見(jiàn)尾文件 ? 則:s中存入實(shí)際讀入的字符,EOF不存入數(shù)組,串尾\0
? ? ? 當(dāng)文件已經(jīng)結(jié)束時(shí),繼續(xù)文件 ? ?則:函數(shù)返回值為空,表示文件結(jié)束
例:fgets(s,4,fp) ? ? ? ?
文本文件內(nèi)容:abcd\n ? ?數(shù)組s:abc\0
? ? ? ? ? ? d\nabc ? ? ? ? ? d\n\0 ? ?
? ? ? ? ? ? ? ? ? ?? fEOF ? ? ? ? ? ? f\0 ?
輸出函數(shù):fputs(s,fp);//其中參數(shù):char s[ ];FIFLE *fp;
//將字符數(shù)組s中的字符串寫(xiě)入文件指針fp所指文件中
//輸入成功返回0,失敗返回EOF
3.格式化輸入輸出
輸入:int fscanf(FILE fp,”格式化字符串”,[輸入項(xiàng)地址表]);
輸出:int fprintf(FILE fp,”格式化字符串”,[輸入項(xiàng)地址表]);
調(diào)用形式:
?輸入函數(shù):fscanf(fp,格式控制符,變量地址表);//其中參數(shù): FIFLE *fp;
//從fp所指向的ASCⅡ文件中讀取字符,按格式控制符的含義存入對(duì)應(yīng)的變量中,返回值為輸入的數(shù)據(jù)個(gè)數(shù)
??輸出函數(shù):fprintf(fp,格式控制符,表達(dá)式列表);//其中參數(shù):FIFLE *fp;
//將表達(dá)式列表中的數(shù)據(jù)按照格式控制符的說(shuō)明,存入fp所指向的ASCⅡ文件,返回值為存入的數(shù)據(jù)個(gè)數(shù)
3.數(shù)據(jù)塊輸入輸出
輸入:int fread(void *buffer,int size,int count,FILE *fp);
輸出:int fwrite(void *buffer,int size,int count,FILE *fp);
調(diào)用形式:
?輸入函數(shù):fread(buffer,size,count,fp);
//從二進(jìn)制文件fp讀取count個(gè)數(shù)據(jù)塊存入buffer中,每個(gè)數(shù)據(jù)塊的大小為size個(gè)字節(jié)
//操作成功,函數(shù)返回值為實(shí)際讀入的數(shù)據(jù)塊數(shù)量,文件結(jié)束或錯(cuò)誤,返回值0
?輸入函數(shù):fwrite(buffer,size,count,fp);
//將buffer中count個(gè)數(shù)據(jù)塊寫(xiě)入二進(jìn)制文件fp中,每個(gè)數(shù)據(jù)塊的大小為size個(gè)字節(jié)
//操作成功,函數(shù)返回值為實(shí)際寫(xiě)入的數(shù)據(jù)塊數(shù)量,文件結(jié)束或錯(cuò)誤,返回值0
四、文件的隨機(jī)讀寫(xiě):
1.位置指針?lè)祷氐筋^文件
函數(shù)原型:void rewind (FILE *fp);
功能:將文件內(nèi)部指針移到文件開(kāi)始位置
2.位置移動(dòng)指針
函數(shù)原型:int fseek(FILE *fp,long off,int whence);
功能:將fp所指文件指針從 whence地址移向offset地址。
whence ?0--文件開(kāi)頭 ?1--文件當(dāng)前位置 ?2--文件的末尾
3.取位置指針
函數(shù)原型:int ftell(FILE *fp); 功能:得到fp所指向文件的當(dāng)前位置,當(dāng)出錯(cuò)時(shí)返回-1L;五、文件檢測(cè):
1.檢測(cè)文件結(jié)束函數(shù):
函數(shù)原型:int feof(FILE *fp);功能:判斷fp所指文件指針是否位于末尾。是返回1,否返回0
2.檢測(cè)文件出錯(cuò)函數(shù):
①檢查數(shù)據(jù)輸入輸出是否出錯(cuò)函數(shù)
函數(shù)原型:int ferror(FILE *fp); 功能:檢查在文件操作時(shí),有沒(méi)有出錯(cuò)。未出錯(cuò)返回0,出錯(cuò)返回1.②清除出錯(cuò)標(biāo)記及文件結(jié)束標(biāo)記
函數(shù)原型:int clearerr(FILE *fp);功能:清除出錯(cuò)標(biāo)記及文件結(jié)束標(biāo)記,使他們值為0六、函數(shù)實(shí)例:
#include<stdio.h> #include<stdlib.h> main() { FILE *fp;int i;char s[20],t[20]; gets(s); //從鍵盤(pán)輸入一個(gè)字符串 fp=fopen("e:\\stu.txt","w");//以寫(xiě)的方式,打開(kāi)E盤(pán)stu.txt文件for(i=0;s[i]!='\0';i++) fputc(s[i],fp);//遍歷字符串中各個(gè)字符通過(guò)fputc();寫(xiě)入文件中fclose(fp);//關(guān)閉文件,完成在txt文本文件中的寫(xiě)操作fp=fopen("e:\\stu.txt","r");//讀的方式打開(kāi)文件fgets(t,6,fp); //注意字符串讀取末尾帶'\0' 從文件中讀取5個(gè)字符加\0存入t數(shù)組printf("The first t is :%s\n",t);printf("The current position is:%d\n",ftell(fp));//顯示讀取字符串后的當(dāng)前指針位置fseek(fp,5,1);//從當(dāng)前位置向后移動(dòng)5個(gè)字節(jié)(4個(gè)字符和\0)printf("The current position is:%d\n",ftell(fp));fgets(t,3,fp);printf("The second t is :%s\n",t);rewind(fp);//重置位置指針到開(kāi)頭位置printf("The current position is:%d\n",ftell(fp));fgets(t,3,fp);printf("The last t is :%s\n",t);fclose(fp); } 輸出結(jié)果:PS:本博客借鑒北京理工大學(xué)C語(yǔ)言程序設(shè)計(jì)和課本總結(jié)而成,有錯(cuò)請(qǐng)指出,謝謝閱讀
總結(jié)
- 上一篇: 电影:美国队长:复仇者先锋
- 下一篇: did双重差分法_Stata中双重差分操