C語言-文件

所謂“文件”是指一組相關數據的有序集合,該數據的集合的名字就是文件名。文件可以分為很多類,如源程序文件、目標文件、可執行文件、庫文件等等。
文件通常是存放在外部介質上的(例如磁盤等),在使用時才會被調入內存中并執行。從用戶的角度來看文件可以分為普通文件和設備文件。
普通文件是指存放在磁盤或者其它外部介質上的一個有序的集合,可以是源文件、目標文件、可執行程序等;也可以是一組待輸入處理的原始數據,或是一組輸出的結果。對于源文件、目標文件、可執行程序可以稱作程序文件,而輸入輸出數據可以稱作數據文件。
設備文件是指與主機相聯的各種外部設備,如顯示器、打印機、鍵盤等。在操作系統中,把外部設備也看作是一個文件來進行管理,把他們的輸入輸出等同于對磁盤文件的讀寫。
從文件編碼的形式來看,文件可以分為ASCII碼文件和二進制碼文件。ASCII碼文件也稱作為文本文件,這種文件在磁盤中存放時每個字符對應一個字節,用于存放相應的ASCII碼。
二進制文件是以二進制編碼的方式來編寫文件的。二進制文件雖然可以顯示在屏幕上,但是卻不能讀懂。

文件的指針

在C語言中用一個指針變量指向一個文件,那么這個指針稱為文件指針。另外,我們通過文件指針就可以對所指的文件進行各種操作。

一般形式為:
FILE* 文件變量標識符

解釋:FILE應該是大寫的,它實際上是由系統定義的一個結構體,該結構體包含了文件名、文件狀態和文件當前位置等信息,因此在編寫程序的時候我們不需要過于關心FILE結構的細節部分。

// 案例1:
FILE *fp;
/*說明:
fp表示FILE結構的指針變量,通過fp可以找到存放某一個文件信息的結構變量,
然后按照結構體提供的信息找到該文件,并對文件進行操作。*/

文件的打開和關閉

文件在進行讀寫操作之前,要打開文件,當使用完后應關閉文件。打開文件就是建立文件的各種有關信息,并使文件指針指向文件,以便進行其他操作。而關閉文件就是切斷文件指針和文件之間的關系,換而言之,就是禁止利用指針操作文件。
在C語言中,文件操作都是由庫函數完成的。如fopen 和 fclose。

1. 文件的打開 fopen()

fopen() 函數是用來打開一個文件,其一般的調用形式為:
文件指針名 = fopen(文件名,使用文件的方式);

注釋:

  1. 文件指針名:必須被說明為FILE類型的指針變量;
  2. 文件名:被打開文件的文件名;
  3. 使用文件的方式:文件的類型和操作要求
// 案例2:
FILE* fp;
fp = fopen("text","r");
/*說明:
在當前目錄下打開文件text,只允許“讀”的操作,并且讓fp指針指向該文件*/

使用文件的方式有12種,如下所示:

|使用文件方 | 意義                                                              |
|----------|------------------------------:|
|“rt”      | 只讀打開一個文本,只允許讀|
|“wt”      | 只寫打開或者建立一個文件,只允許寫數據|
|“at”      | 追加打開一個文件,并在文件末尾寫數據|
|“rb”      | 只讀打開一個二進制文件,只允許讀|
|“wt”      | 只寫打開或者建立一個而進制文件,只允許寫|
|“ab”      | 追加打開一個二進制文件,并在文件末尾寫數據|
|“rt+”     | 讀寫打開一個文件,允許讀和寫 |
| “wt+”    | 讀寫打開或建立一個文件,允許讀寫|
|“at+”     | 讀寫打開一個文件,允許讀,或在文件末尾追加數據|
|“rb+”     | 讀寫打開一個二進制文件,允許讀寫|
|“wb+”     | 讀寫打開或者建立一個二進制文件,允許讀寫        |
|“ab+”     | 讀寫打開一個二進制文件,允許讀,或在文件末追加數據|

說明:
由r、w、a、t、b、+六個字符拼成,個字符的意義:

  1. r(read):讀
  2. w(write):寫
  3. a(append):追加
  4. t(text):文本文件,可省略不寫
  5. b(banary):二進制文件
    6.+:讀和寫
// 案例3:
FILE* fp;
fd = fopen("./text","r");
if (NULL == fd)
{
    printf("open error\n");
    exit(1);
}
// 用讀“r”的方式打開文件“./text”;若文件打開失敗時,fp為空,輸出open error。

2. 文件的關閉

fclose()函數是指當文件使用完后,需要關閉文件。其一般形式為:
fclose(文件指針);

// 案例4:
fclose(fp);
// 說明:正常關閉文件時,fclose()函數的返回值是0。若返回一個非零的值,則表示關閉文件時發生錯誤

文件的讀寫

文件的讀寫是有多重方式的,它可以一個字節一個字節的讀或寫,也可以是一串一串的讀或寫。文件的讀寫可以分為下面四類,且它們的頭文件均是<stdio.h>。

1. 字符讀寫函數fgetc 和 fputc

字符的讀寫函數是以字節為單位讀寫函數。每一次可以從文件讀出或向文件內寫入一個字符。
讀字符函數fgetc() 的一般形式:
字符變量 = fgetc(文件指針);

說明:將文件中的一個字符讀取出來,然后存放在字符變量中。

寫字符函數fputs() 的一般形式:
fputs(字符量,文件指針);

說明:將字符量中的字符,存放在想對應的文件中。

// 案例5:
#include<stdio.h>

int main()
{
    FILE* fp = fopen("./text","r");
    if (NULL == fp)
    {
      printf("cann't open the file\n");
      exit(1);
    }
    char ch; 
    // 讀取文件中的字符,一個一個的讀取。
    ch = fgetc(fp);
    while (EOF != ch)  // EOF表示讀到文件的末尾
    {
      printf("%c\n",ch);
      ch = fgetc(fp);
    }
    close(fp);
    // 向文件中寫入數據
    fp = fopen("./text1","w");
    if (NULL == fp)
    {
      printf("cann't open the file\n");
      exit(1);
    }
    printf("input a character:");
    scanf("%c",&ch);
    fputc(ch,fp); // 將ch變量中的字符存放到文件“./text1”中。
    return 0;
}

注意:在網文件中寫數據的時候,上的那種寫法是,直接覆蓋文件中的數據,而不是在文件的末尾追加數據。若想不改變文件原來的數據,只想在文件的末尾追加數據,那么需要將文件的打開方式“w”更改為“a”,這樣我們就可以在原數據的基礎上追加數據。

2. 字符串讀寫函數fgets 和 fputs

fgets() 的一般形式:
fgets(字符數組名,n,文件指針);

說明:n是一個正整數,表示從文件中讀取的字符串不超過n-1個字符,在讀入最后一個字符后加上結束符'\0'。

fputs()的一般形式:
fputs(字符數組名,文件指針);

說明:字符數組名,首先其中必須是一個已被初始化的字符數組,即里面有值;也可以用一個字符串常量(或指針變量)代替字符數組名。

//案例6:
#include<stdio.h>

int main()
{
    char ch[20];
    FILE *fp = fopen("./text","rw");
    if (NULL == fp)
    {
      printf("open error\n");
      exit(1);
    }
    printf("input what you want to say:");
    scanf("%s",ch);
    //將字符串ch中的值寫在文件text中。
    fputs(ch,fp);
    char ch2[30];
    // 從文件中讀取數據,并由ch2字符串變量接收。
    fgets(ch2,sizeof(ch2)-1,fp);
    printf("ch2:%s\n",ch2);
    return 0;
}

3. 數據塊讀寫函數fread 和fwrite

C語言中不僅提供了字符、字符串的讀寫方式,同時也提供了數據塊的讀寫方式。它們可用來讀寫一組數據,如:一個數組元素,一個結構變量的值等。
fread()的一般形式:
fread(buffer,size,count,fp);
fwrite()的一般形式:
fwrite(buffer,size,count,fp);

說明:

  1. buffer 是一個指針,在fread函數中表示存放數據的首地址。在fwrite函數中表示輸出數據的首地址;
  2. size 表示數據塊的字節數;
  3. count 表示要讀寫的數據塊的塊數
  4. fp 表示文件的指針
//案例7:
#include<stdio.h>
struct student
{
    int id;
    char name[20];
    float score;
};

int main()
{
    struct student boy[2];
    int i = 0;
    for (;i < 2; i++)
    {
      printf("input the student's infomation(id, name, score):");
      scanf("%d%s%f",&boy[i]->id,boy[i]->name,&boy[i]->score);
    }
    
    FILE* fp;
    fp = fopen("./student.text","w+");
    if (NULL == fp)
    {
      printf("open file error\n");
      exit(1);
    }
    
    fwrite(boy,sizeof(struct student),2,fp);
    rewind(fp);
    struct student stu[2];
    fread(stu,sizeof(struct student),2,fp);
    printf("id\tname\tscore\n");
    for (i = 0; i < 2; i++)
    {
      printf("%d\t%s\t%f\n",stu[i]->id,stu[i]->name,stu[i]->score);
    }
    return 0;
}

4. 格式化讀寫函數fscanf 和 fprintf

fscanf、fprintf和scanf、printf的區別:
fscanf和fprintf函數的讀寫不是對鍵盤和顯示器的,而是對磁盤文件;不過它們都是格式化讀寫函數。

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

//案例8:
#include<stdio.h>
int main()
{
    char caBuf[3][32] = {'\0'};
    int i = 0;
    
    for (; i < 3; i++)
    {
      printf("input :");
      scanf("%s", caBuf[i]);
    }
    
    FILE *fp;
    fp = fopen("./MyInput", "wb+");
    if (NULL == fp)
    {
      printf("open file error\n");
      exit(1);
    }
    for (i=0; i < 3; i++)
    {
      fprintf(fp, "%s", caBuf[i]);
    }
    rewind(fp);
    char sMsg[32] = {'\0'};
    for(i=0; i < 3; i++)
    {
      fscanf(fp, "%s", sMsg);
      printf("sMsg: %s\n", sMsg);
    }
    fclose(fp);
    return 0;
}

文件定位

有的時候我們在讀寫文件時,不想從開頭或者末尾開始讀或者寫;想讀取中間的內容,或者是想將一段數據插入到文件中間,我們該怎么做?這時候,我們就需要引入新的知識,文件的定位。

文件定位函數

在文件定位中,主要有兩個函數:rewind()和fseek().
rewind() 在前面已經使用,并進行一定的說明,不過在這里還是要重申一下,其一般形式為:
rewind(文件指針);

功能:文件內部的文件指針轉移到文件首部。

fseek() 的一般形式:
fseek(文件指針, 位移量, 起始點);

參數說明:
文件指針:被指向移動的文件;
位移量:表示移動的字節數;
起始點:表示從何處開始計算位移量,規定有三種:文件首部(SEEK_SET,1),當前位置(SEEK_CUR,0)和文件尾部(SEEK_END, 2)。

// 案例10:
fseek(fp, 100, 0);
//表示:把文件位置指針移到距離首部100個字節處。

注意事項:fseek()一般用于二進制文件。在文本文件中由于要進行轉換,故往往計算位置會出現錯誤

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • [TOC] UNIX的哲學,萬物皆文件. 打開關閉文件 FILE * fopen(const char *file...
    robinguo2012閱讀 743評論 0 0
  • 文件指針 FILE * 指針變量標識符作用:通過該指針即可找到存放某個文件信息的結構變量,然后按結構變量提供的信息...
    永斷閻羅閱讀 467評論 0 3
  • 語言中對文件進行操作必須首先打開文件,打開文件主要涉及到fopen函數。fopen函數的原型為 FILE* fop...
    朱森閱讀 825評論 0 1
  • 文件操作是實際應用的重要部分,本文基于C程序設計(譚浩強版)所寫。 C語言文件讀寫 fopen,fclose(打開...
    靜候那一米陽光閱讀 395評論 0 0
  • 或許再過幾個年頭,我們都會分開,可是終歸我們曾經相遇過,我對你最大的期望便是健康就好! 很多時候,我們覺得我們是主...
    失憶路人甲yu閱讀 317評論 0 0