c——檔案讀寫

來源:互聯網
上載者:User
 

   


第十三章 檔案

學習要求:

1.理解檔案的概念
2.掌握檔案的開啟與關閉的方法
3.掌握檔案的讀寫、定位及出錯檢測的方法

內容:

C檔案概述

1、“檔案(file)”:所謂“檔案”是指一組相關資料的有序集合。資料以檔案的形式存放在外部介質(一般是磁碟、磁帶、光碟片等)上,在作業系統中是以檔案為單位對資料進行管理的。以檔案名稱作為訪問檔案的標識。

2、C語言把檔案看作一個位元組序列,即由一連串的位元組組成。根據檔案中的資料群組織形式,資料檔案可分為ASCII碼檔案和二進位檔案。

ASCII碼檔案,又稱為“文字檔”(text),其每一個位元組存放一個ASCII碼。

二進位檔案,把記憶體中的資料按其在記憶體中的儲存形式存放在磁碟上。

例:十進位整數10000,在記憶體中佔兩個位元組,其存放形式是:00100111,00010000。在二進位檔案中也按這種方式存放。

但是,在ASCII檔案中,十進位整數10000存放為31H、30H、30H、30H、30H,佔五個位元組,它們分別是1、0、0、0、0、0字母的ASCII碼。

3、按照作業系統對磁碟檔案的讀寫方式,檔案可以分為“緩衝檔案系統”和“非緩衝檔案系統”。

緩衝檔案系統:作業系統在記憶體中為每一個正在使用的檔案開闢一個讀寫緩衝區。從記憶體向磁碟輸出資料必須先送到記憶體中的緩衝區,裝滿緩衝區後才一起送到磁碟上。如果從磁碟向記憶體讀入資料,則一次從磁碟檔案將一批資料輸入到記憶體緩衝區,然後再從緩衝區逐個地將資料送到程式資料區。

 

非緩衝檔案系統:指作業系統不自動開闢確定大小的讀寫緩衝區,而由程式為每個檔案設定緩衝區。

在UNIX系統下,用緩衝檔案系統來處理文字檔,用非緩衝檔案系統處理二進位檔案。ANSI C標準只採用緩衝檔案系統。

在C語言中,沒有輸入輸出語句,對檔案的讀寫都是用庫函數來實現的。本章只介紹ANSI C標準規定的緩衝檔案系統。

檔案類型指標

緩衝檔案系統中,每一個使用的檔案都在記憶體中開闢一個“檔案資訊區”,用來存放檔案的相關資訊(檔案的名字、檔案當前的讀寫位置、檔案操作方式等)。這些資訊儲存在一個結構體變數中,該結構體是由系統定義的,取名為FILE。Turbo C 3.0 在stdio.h檔案中有以下檔案類型的聲明:

 

typedef struct {
int level;                /* 緩衝區“滿”或“空”的程度 */
unsigned flags;           /* 檔案狀態標誌 */
char fd;                  /* 檔案描述符*/
unsigned char hold;       /* 如無緩衝區不讀取字元 */
int bsize;                /* 緩衝區的大小 */
unsigned char *buffer;    /* 資料緩衝區的位置*/
unsigned char *curp;      /* 指標,當前的指向 */
unsigned istemp;          /* 臨時檔案,指標 */
short token;              /* 用於有效性檢查 */
} FILE;                   

定義檔案指標變數的一般形式為:

   FILE *檔案結構指標變數名

例如:FILE *fp;

注意:只有通過檔案指標,才能調用相應的檔案。

檔案的開啟(fopen函數)

檔案操作的過程:對磁碟檔案的操作必須“先開啟,後讀寫,最後關閉”。

“開啟”檔案的含義:以某中方式從磁碟上尋找指定的檔案或建立一個新檔案。

ANSI C規定了標準輸入輸出函數庫,用 fopen()函數開啟檔案。fopen()函數的調用方式一般為:

FILE *fp;

fp=fopen(檔案名稱,使用檔案方式);

 

例如:

  FILE *fp;

aaaafp = fopen("file1","r");

表示要開啟名字為file1的檔案,使用檔案方式為“讀入”,如果開啟成功,返回一個指向file1檔案的指標;如果開啟失敗,返回一個NULL指標。

使用檔案方式見下表:

使用檔案方式

含義

"r"(唯讀) 為輸入開啟一個文字檔
"w"(唯寫) 為輸出開啟一個文字檔
"a"(追加) 為追加開啟一個文字檔
"rb"(唯讀) 為輸入開啟一個二進位檔案
"wb"(唯寫) 為輸出開啟一個二進位檔案
"ab"(追加) 為追加開啟一個二進位檔案
"r+"(讀寫) 為讀/寫開啟一個文字檔
"w+"(讀寫) 為讀/寫建立一個文字檔
"a+"(讀寫) 為讀/寫開啟一個文字檔
"rb+"(讀寫) 為讀/寫開啟一個二進位檔案
"wb+"(讀寫) 為讀/寫建立一個二進位檔案
"ab+"(讀寫) 為讀/寫開啟一個二進位檔案

 

說明:

1、用"r"方式開啟的檔案只能用於向電腦輸入而不能用作向該檔案輸出資料,而且該檔案應該已經存在,不能用"r"方式開啟一個不存在的檔案(即輸入檔案),否則出錯。

2、用"w"方式開啟的檔案只能用於向該檔案寫資料(即輸出檔案),而不能用來向電腦輸入。如果原來不存在該檔案,則在開啟時建立一個檔案,如果該檔案存在,則先刪除該檔案,然後重建立立一個新檔案。

3、如果希望向檔案尾添加新資料(不刪除原有資料),則應該用"a"方式開啟。但要求此時檔案必須存在,否則出錯。

4、用"r+"、"w+"、"a+"方式開啟的檔案即可以用來輸入資料,也可以用來輸出資料。

5、如果不能實現開啟檔案的任務,fopen()函數將帶回一個出錯資訊。用帶"r"的方式("r"、"rb"、"r+"、"rb+")開啟檔案時,若檔案不存在,則返回NULL指標。

常用以下方式開啟檔案:

   FILE *fp;

   if ((fp=fopen("file1", "r")) ==NULL )

   {
printf("cannot open this file\n");

    exit(0);

   }

 即如果有錯就在終端上輸出"cannot open this file"。exit()函數的作用是關閉所有檔案,終止正在執行的程式。

6、在向電腦輸入文字檔時,將斷行符號分行符號轉換為一個分行符號,在輸出時把分行符號轉換為斷行符號和換行兩個字元。在用二進位檔案時,不進行轉換。

 

檔案的關閉(fclose函數)

在使用完一個檔案後應該關閉它,“關閉”檔案就是使檔案指標與檔案脫離,此後不能再通過該指標對原來與其相聯絡的檔案進行讀寫操作。應養成在程式終止前關閉所有檔案的習慣。

用fclose函數關閉檔案。fclose函數調用的一般形式為:

fclose(檔案指標)

例如:

fclose(fp);

fclose函數也帶回一個傳回值,當順利關閉檔案時,返回0,否則返回EOF(-1)。

檔案的讀寫

當檔案開啟後,就可以對它進行讀寫了。常用的讀寫函數如下所述。

1、fputc函數和fgetc函數(putc函數和getc函數)

(1)、fputc函數

把字元寫入到磁碟檔案,一般的調用方式為:

fputc(ch,fp)

把字元(ch的值)寫入fp所指向的檔案中去。成功時返回字元ch的ASCII碼,失敗時返回

EOF(在stdio.h中,符號常量EOF的值等於-1)。

 

(2)、fgetc()函數

從指定檔案讀入一個字元。fgetc函數的調用形式為:

ch=fgetc(fp);

從fp所指向的檔案中讀一個字元,返回讀得的字元給變數ch。對於文字檔,遇檔案尾時返迴文件結束標誌EOF。對於二進位檔案,用feof(fp) 判別是否遇檔案尾,feof(fp)=1說明遇檔案尾。

從文字檔中順序讀入檔案內容,並在螢幕上顯示出來,可以用:

 ch = fgetc(fp);

 while(ch != EOF)

 {
putchar(ch);

  ch = fgetc(fp);
}

從二進位檔案中順序讀入檔案內容,可以用:

 while(!feof(fp))
{
ch = fgetc(fp);
....
}

這種方法也適用於文字檔。

 

(3)、fputc函數和fgetc函數應用舉例

例子13_1 從鍵盤輸入一些字元,逐個把它們送入磁碟檔案,直到從鍵盤輸入#為止。

例子13_2  將一個磁碟檔案的內容複寫到另一個磁碟檔案。

fread函數和fwrite函數

fread函數和fwrite函數用來讀寫一個資料區塊。它們的一般調用方式為:

fread(buffer,size,count,fp);

fwrite(buffer,size,count,fp);

其中:

buffer:是一個指標。對fread來說,它是讀入資料的存放地址。對fwrite來說,是要輸出資料的地址。

size:要讀寫的位元組數。

count:要進行讀寫多少個size位元組的資料項目。

fp:檔案型指標。

如果以二進位形式開啟檔案,用fread函數和fwrite函數就可以讀寫任何類型的資訊,例如:

fread(f,4,2,fp);

其中f是一個實型數組名。一個實型變數佔4個位元組。這個函數從fp所指向的檔案讀入2個4個位元組的資料,儲存到數組f中。

 

如果有如下的結構體類型:

  struct student_type
{
char name[10];

   int num;

   int age;

   char addr[30];

  }stu[40];

結構體數組stu有40個元素,每一個元素用來存放一個學生的資料。假設學生的資料已經存放在磁碟檔案中,可以用下面的for語句和fread函數讀入40個學生的資料:

for(i=0; i<40; i++)

  fread(&stu[i], sizeof(struct student_type), 1, fp);

  或:

  fread(&stu[i], sizeof(struct student_type), 40, fp);

 

同樣,以下程式可以將記憶體中的學生資料輸出到磁碟檔案中去:

  for(i=0; i<40; i++) /* 每次寫一個學生 */

  fwrite(&stu[i], sizeof(struct student_type), 1, fp);

  或者唯寫一次

  fwrite(stu, sizeof(struct student_type), 40, fp);  

例子13_3 從鍵盤上輸入一批學生資料,然後儲存到磁碟上。

fprintf函數和fscanf函數

fprintf函數、fscanf函數與printf函數、scanf函數的作用相仿,都是格式化讀寫函數。fprintf和fscanf函數的讀寫對象是磁碟檔案,而printf和scanf函數的讀寫對象是終端。

它們的一般調用格式為:

fprintf(檔案指標,格式字串,輸出資料行表);

fscanf (檔案指標,格式字串,輸入列表);

除增加“檔案指標”外,其他與printf()/scanf()用法相同。

例如:

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

它的作用是將整型變數i和實型變數t的值按%d和%6.2f的格式輸出到fp所指向的檔案中。如果i=3,t=4.5,則輸出到磁碟檔案上的是以下字串:

3,4.50

 

同樣,用fscanf函數可以從磁碟檔案上讀入ASCII字元:

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

磁碟檔案上如果有以下字元:3,4.5  則將磁碟檔案的資料3送給變數i,4.5送給變數t。

用fprintf和fscanf函數對磁碟檔案操作,由於在輸入時要將ASCII碼轉換為二進位形式,在輸出時又要將二進位轉換為字元,花費時間比較多,因此,在記憶體與磁碟頻繁交換資料的情況下,最好不用fprintf和fscanf函數,而用fread和fwrite函數。

其他讀寫函數

1、putw和getw函數

putw和getw函數用來對磁碟檔案讀寫一個字(整數)。例如:

putw(10,fp);    /* 整數10寫入檔案fp */

i=getw(fp);     /* 從檔案fp讀一個整數給變數i */

2、fgets和fputs函數

fgets函數的作用是從指定檔案讀入一個字串。例如:

fgets(str, n,fp)     /* 從檔案fp讀n-1個位元組到str,str最後一個位元組加'\0'*/

fputs函數的作用是向指定的檔案輸出一個字串。例如:

fputs(str,fp)        /* 把字串str寫入fp */

 

檔案的定位

檔案中有一個位置指標,指向當前讀寫的位置。每當進行一次讀寫後,該指標自動指向下一個字元的位置。可以用ftell()函數獲得當前的位置指標,也可以用rewind()/fseek()函數改變位置指標,使其指向需要讀寫的位置。

1、rewind函數

一般的使用形式為:rewind(fp);作用:使檔案fp的位置指標指向檔案開始。

例子13_4 把一個檔案的內容顯示在螢幕上,並同時複製到另一個檔案。

2、fseek函數和隨機讀寫

對流式檔案可以進行順序讀寫,也可以進行隨機讀寫,關鍵在於控制檔案的位置指標。

用fseek函數可以實現改變檔案的位置指標。fseek函數的調用形式為:

fssek (檔案類型指標,位移量,起始點);

功能:把檔案的位置指標從起始點開始,移動指定位移量的位元組數。成功返回0,失敗返回非0。

起始點 符號常量
檔案開始位置 SEEK_SET 0
當前位置 SEEK_CUR 1
檔案尾 SEEK_END 2

例子13_5  在磁碟檔案stud_dat上,存有10個學生(0~9)的資料,讀出1、3、5、7、9號學生資料,並在螢幕上顯示出來。

 

3、ftell函數

ftell函數的作用是得到流式檔案中的當前位置,用相對於檔案開頭的位移量來表示。若失敗則傳回值為-1L。

例如:

i=ftell(fp);

if(i==-1L) printf("error\n");

變數i存放當前位置,如調用函數時出錯(如不存在fp檔案),則輸出"error"。

出錯的檢測

C 標準提供一些函數用來檢查輸入輸出函數調用中的錯誤。

1、ferror函數

在檔案操作時,如果出錯,除了操作函數的傳回值有所反應外(如fopen()函數返回NULL),還可以用ferror函數獲得是否出錯。它的一般調用形式為:

ferror(fp)

功能:若上一次檔案操作未出錯,返回0;否則返回非0。

2、clearerr函數

clearerr函數的作用是使檔案錯誤標誌和檔案結束標誌置為0。 檔案操作出現錯誤後,ferror(fp)函數值為一個非0值,該錯誤資訊將一直保留在系統中,在調用clearerr(fp)函數後,ferror(fp)函數值變成0。

檔案輸入輸出小結

常用的緩衝檔案系統函數

分類 函數名 功能
開啟檔案

fopen()

開啟檔案。
關閉檔案 fclose() 關閉檔案。
檔案定位

fseek()

rewind()

ftell()

改變檔案位置指標位置

使檔案位置指標重新置於檔案開頭

返迴文件位置指標的當前值

檔案讀寫

fgetc(),getc()

fputc(),putc()

fgets()

fputs()

getw()

putw()

fread()

fwrite()

fscanf()

fprintf()

從指定檔案取得一個字元。

把字元輸出到指定檔案。

從指定檔案讀取字串。

把字串輸出到指定檔案。

從指定檔案讀取一個字(int型)。

把一個字(int型)輸出到指定檔案。

從指定檔案中讀取資料項目。

把資料項目寫到指定檔案。

從指定檔案按格式輸入資料。

按指定格式將資料寫到指定檔案中。

檔案狀態

feof()

ferror()

clearerr()

若到檔案末尾,函數值為“真”(非0)。

若對檔案操作出錯,函數值為“真”(非0)。

使ferror和feof函數值置零。

 

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.