十五、文件
15.1 C 文件概述
所謂“文件”是指一組相關數(shù)據(jù)的有序集合。這個數(shù)據(jù)集有一個名稱,叫做文件名。文件通常是駐留在外部介質(如磁盤等)上的,在使用時才調入內(nèi)存中來。
從不同的角度可對文件作不同的分類。從用戶的角度看,文件可分為普通文件和設備文件兩種。普通文件 是指駐留在磁盤或其它外部介質上的一個有序數(shù)據(jù)集,可以是源文件、目標文件、可執(zhí)行程序;也可以是一組待輸入處理的原始數(shù)據(jù),或者是一組輸出的結果。對于源文件、目標文件、可執(zhí)行程序可以稱作程序文件,對輸入輸出數(shù)據(jù)可稱作數(shù)據(jù)文件。設備文件 是指與主機相聯(lián)的各種外部設備,如顯示器、打印機、鍵盤等。在操作系統(tǒng)中,把外部設備也看作是一個文件來進行管理,把它們的輸入、輸出等同于對磁盤文件的讀和寫。
通常把顯示器定義為 標準輸出文件,一般情況下在屏幕上顯示有關信息就是向標準輸出文件輸出。如前面經(jīng)常使用的printf, putchar函數(shù)就是這類輸出。鍵盤通常被指定為 標準輸入文件,從鍵盤上輸入就意味著從標準輸入文件上輸入數(shù)據(jù)。scanf, getchar函數(shù)就屬于這類輸入。
從文件編碼的方式來看,文件可分為 ASCII 碼文件 和 二進制碼文件 兩種。ASCII 文件也稱為文本文件,這種文件在磁盤中存放時每個字符對應一個字節(jié),用于存放對應的ASCII 碼;二進制文件是按二進制的編碼方式來存放文件的。
ASCII 碼文件可在屏幕上按字符顯示,例如源程序文件就是ASCII 文件,用DOS命令TYPE可顯示文件的內(nèi)容。由于是按字符顯示,因此能讀懂文件內(nèi)容。二進制文件雖然也可在屏幕上顯示,但其內(nèi)容無法讀懂。
C系統(tǒng)在處理這些文件時,并不區(qū)分類型,都看成是字符流,按字節(jié)進行處理。輸入輸出字符流的開始和結束只由程序控制而不受物理符號(如回車符)的控制。因此也把這種文件稱作 “流式文件”。
15.2 文件指針
在C語言中用一個指針變量指向一個文件,這個指針稱為文件指針。通過文件指針就可對它所指的文件進行各種操作。
其定義的一般形式為:FILE *指針變量標識符;
其中 FILE 為大寫,它實際上是由系統(tǒng)定義的一個結構,該結構中含有文件名、文件狀態(tài)和文件當前位置等信息,在編寫源程序時不必關心FILE結構的細節(jié)。
FILE *fp;
//表示fp是指向FILE結構的指針變量,通過fp即可找存放某個文件信息的結構變量,然后按結構變量提供的信息找到該文件,實施對文件的操作。
//習慣上也籠統(tǒng)地把fp稱為指向一個文件的指針。
15.3 文件的打開與關閉
文件在進行讀寫操作之前要先打開,使用完畢要關閉。所謂打開文件,實際上是建立文件的各種有關信息,并使文件指針指向該文件,以便進行其它操作。關閉文件則斷開指針與文件之間的聯(lián)系,也就禁止再對該文件進行操作。在C語言中,文件操作都是由庫函數(shù)來完成的。
15.3.1文件打開( fopen 函數(shù)):
其使用的一般形式為:文件指針名 = fopen(文件名,使用文件方式);
其中,文件指針名必須是被說明為FILE 類型的指針變量;文件名是被打開文件的文件名;使用文件方式是指文件的類型和操作要求;文件名是字符串常量或字符串數(shù)組。
FILE *fp;
fp = fopen("c:\\abc2", "rb"); //表示打開 C 盤下的 abc2 (二進制)文件,只允許進行讀操作;
//兩個反斜線 “//” 中的第一個表示轉義字符,第二個表示根目錄。
使用文件的 12 種方式
對于文件使用方式的幾點說明:
(1)共由 6 個字符 r, w, a, t, b, +
拼接而成,各個字符的含義為:
字符 | 含義 |
---|---|
r(read) | 讀 |
w(write) | 寫 |
a(append) | 追加 |
t(text) | 文本文件(可省略) |
b(banary) | 二進制文件 |
+ | 讀、寫 |
(2)凡用 “r” 打開一個文件時,該文件必須已經(jīng)存在,且只能從該文件讀出;
(3)用 “w” 打開的文件只能向該文件寫入。若打開的文件不存在,則以指定的文件名建立該文件,若打開的文件已經(jīng)存在,則將該文件刪去,重建一個新文件;
(4)若要向一個已存在的文件追加新的信息,只能用 “a” 方式打開文件。但此時該文件必須是存在的,否則將會出錯。
(5)在打開一個文件時,如果出錯,fopen 將返回一個空指針值NULL。在程序中可以用這一信息來判別是否完成打開文件的工作,并作相應的處理。因此常用以下程序段打開文件:
FILE *fp;
if(fp = fopen("c:\\abc2", "rb")==NULL)
{
printf("\nerror open!");
getch(); //從鍵盤輸入一個字符,但不在屏幕上顯示;
//(其作用為等待,只有當用戶從鍵盤任意敲一個鍵時,程序再繼續(xù)執(zhí)行)
exit(1); //敲鍵后執(zhí)行 exit(1) 退出程序
}
(6)把一個文本文件讀入內(nèi)存時,要將ASCII 碼轉換成二進制碼,而把文件以文本方式寫入磁盤時,也要把二進制碼轉換成ASCII 碼,因此文本文件的讀寫要花費較多的轉換時間。對二進制文件的讀寫不存在這種轉換。
(7)標準輸入文件(鍵盤),標準輸出文件(顯示器),標準出錯輸出(出錯信息)是由系統(tǒng)打開的,可直接使用。
15.3.2 文件關閉( fclose 函數(shù)):
fclose(文件指針);
正常完成關閉文件操作時,fclose 函數(shù)返回值為0。如返回非零值則表示有錯誤發(fā)生。
15.4 文件讀寫
15.4.1 字符讀寫函數(shù)
以字符(字節(jié))為單位的讀寫函數(shù)。每次可從文件讀出或向文件寫入一個字符。
1 . 讀字符函數(shù) fgetc,從指定文件中讀一個字符,形式為:字符變量 = fgetc(文件指針);
ch = fgetc(fp); //從打開的文件fp中讀取一個字符并送入ch 中。
說明:
(1)在 fgetc 函數(shù)調用中,讀取的文件必須是以讀或讀寫方式打開的;
(2)讀取字符的結果也可以不向字符變量賦值,但這樣讀出的字符不能保存;
(3)在文件內(nèi)部有一個位置指針。用來指向文件的當前讀寫字節(jié)。在文件打開時,該指針總是指向文件的第一個字節(jié)。使用fgetc函數(shù)后,該位置指針將向后移動一個字節(jié)。因此可連續(xù)多次使用fgetc函數(shù),讀取多個字符。應注意文件指針和文件內(nèi)部的位置指針不是一回事。文件指針是指向整個文件的,須在程序中定義說明,只要不重新賦值,文件指針的值是不變的。文件內(nèi)部的位置指針用以指示文件內(nèi)部的當前讀寫位置,每讀寫一次,該指針均向后移動,它不需在程序中定義說明,而是由系統(tǒng)自動設置的。
2 . 寫字符函數(shù) fputc,把一個字符寫入指定的文件中,形式為:fputc(字符量, 文件指針);
其中,待寫入的字符量可以是字符常量或變量。
fputc('a', fp); //把字符 a 寫入 fp 所指向的文件中
說明:
(1)被寫入的文件可以用寫、讀寫、追加方式打開,用寫或讀寫方式打開一個已存在的文件時將清除原有的文件內(nèi)容,寫入字符從文件首開始。如需保留原有文件內(nèi)容,希望寫入的字符以文件末開始存放,必須以追加方式打開文件。被寫入的文件若不存在,則創(chuàng)建該文件。
(2)每寫入一個字符,文件內(nèi)部位置指針向后移動一個字節(jié)。
(3)fputc 函數(shù)有一個返回值,如寫入成功則返回寫入的字符,否則返回一個EOF??捎么藖砼袛鄬懭胧欠癯晒?。
15.4.2 字符串讀寫函數(shù)
1 . 讀字符串函數(shù) fgets,從指定的文件中讀一個字符串到字符數(shù)組中,形式為:fgets(字符數(shù)組名, n, 文件指針);
其中的n是一個正整數(shù)。表示從文件中讀出的字符串不超過n-1個字符。在讀入的最后一個字符后加上串結束標志 ’\0’ 。
fgets(str, n, fp); //從 fp 所指的文件中讀出 n-1 個字符送入字符數(shù)組 str 中
說明:
(1)在讀出n-1個字符之前,如遇到了換行符或EOF,則讀出結束。
(2)fgets 函數(shù)也有返回值,其返回值是字符數(shù)組的首地址。
2 . 寫字符串函數(shù) fputs,向指定的文件寫入一個字符串,其形式為:fputs(字符串, 文件指針);
其中字符串可以是字符串常量,也可以是字符數(shù)組名,或指針變量。
fputs("abcd", fp); //將字符串 abcd 寫入 fp 所指的文件中
15.4.3 數(shù)據(jù)塊讀寫函數(shù)
讀數(shù)據(jù)塊函數(shù):fread(buffer, size, count, fp);
寫數(shù)據(jù)塊函數(shù):fwrite(buffer, size, count, fp);
其中,buffer 是一個指針,在fread函數(shù)中,它表示存放輸入數(shù)據(jù)的首地址。在fwrite函數(shù)中,它表示存放輸出數(shù)據(jù)的首地址;
size表示數(shù)據(jù)塊的字節(jié)數(shù);
count表示要讀寫的數(shù)據(jù)塊塊數(shù);
fp表示文件指針。
fread(fa, 4, 5, fp);
//從fp所指的文件中,每次讀4個字節(jié)(一個實數(shù))送入實數(shù)組fa中,連續(xù)讀5次,即讀5個實數(shù)到fa中。
15.4.4 格式化讀寫函數(shù)
fscanf函數(shù),fprintf 函數(shù)與前面使用的scanf和 printf函數(shù)的功能相似,都是格式化讀寫函數(shù)。兩者的區(qū)別在于fscanf 函數(shù)和 fprintf函數(shù)的讀寫對象不是鍵盤和顯示器,而是磁盤文件。
格式化讀函數(shù):fscanf(文件指針,格式字符串, 輸入表列);
格式化寫函數(shù):fprintf(文件指針,格式字符串, 輸出表列);
15.5 文件的隨機讀寫
順序讀寫,即讀寫文件只能從頭開始,順序讀寫各個數(shù)據(jù)。但在實際問題中常要求只讀寫文件中某一指定的部分。為了解決這個問題可移動文件內(nèi)部的位置指針到需要讀寫的位置,再進行讀寫,這種讀寫稱為隨機讀寫。實現(xiàn)隨機讀寫的關鍵是要按要求移動位置指針,這稱為文件的定位。
15.5.1文件定位
1 . rewind 函數(shù),將文件內(nèi)部的位置指針移動到文件首。形式為:rewind(文件指針);
2 . fseek 函數(shù),移動文件內(nèi)部位置指針,形式為:fseek(文件指針, 位移量, 起始點);
注意, fseek 函數(shù)一般用于二進制文件。
其中,“文件指針” 指向被移動的文件;
“位移量"表示移動的字節(jié)數(shù),要求位移量是long型數(shù)據(jù),以便在文件長度大于64KB時不會出錯。當用常量表示位移量時,要求加后綴”L”。
"起始點"表示從何處開始計算位移量,規(guī)定的起始點有三種:文件首,當前位置和文件尾,其表示方法為:文章來源:http://www.zghlxwxcb.cn/news/detail-768251.html
fseek(fp, 100L, 0); //把位置指針移動到離文件首 100 個字節(jié)出
15.5.2 文件檢測函數(shù)
1 . 文件結束檢測函數(shù)(feof 函數(shù)),功能為判斷文件是否處于文件結束位置,如文件結束,則返回值為1,否則為0。
格式為:feof(文件指針);
2 . 讀寫文件出錯檢測函數(shù)(ferror 函數(shù)),功能為檢查文件在用各種輸入輸出函數(shù)進行讀寫時是否出錯。如 ferror 返回值為 0 表示未出錯,否則表示有錯。
格式為:ferror(文件指針);
3 . 文件出錯標志和文件結束標志置 0 函數(shù)(clearerr 函數(shù)),用于清除出錯標志和文件結束標志,使它們?yōu)?0 值。
格式為:clearerr(文件指針);
文章來源地址http://www.zghlxwxcb.cn/news/detail-768251.html
到了這里,關于C語言基礎——文件的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網(wǎng)!