C語言 fopen和fread函數解析

fopen函數

fopen()函數可以用來打開文件,寫法如下,第一個參數是文件名路徑,第二個參數的是打開文件的方式:

FILE *fp1;
fp1 = fopen("file a","r");//r代表read,表示只讀
FILE *fp2;
fp2 = fopen("c:\\hzk16","rb");//讀取c盤的hzk16文件,r代表read,b代表binary,表示只讀二進制文件

一共有六種符號:

r: read 讀
w: write 寫
t: text 文本文件
b: binary 二進制文件
+: both read and write 讀寫
a: append 末尾追寫

以下是最基本的只讀只寫的操作

FILE *fp;
fp = fopen("fileA","rt");//打開一個文本文件,文件必須存在,只允許讀,rt: read text
fp = fopen("fileA","r");//"r" = "rt", 因爲默認打開text

fp = fopen("fileA","rb");//打開一個二進制文件,文件必須存在,只允許讀

fp = fopen("fileA","w");//新建一個文本文件,若存在原有文件則清空,只允許寫
fp = fopen("fileA","wt");//"w" = "wt", 因爲默認打開text

fp = fopen("fileA","wb");//新建一個二進制文件,若存在原有文件則清空,只允許寫

如果只允許在文件的末尾進行寫入操作,可以用以下方式:

FILE *fp;
fp = fopen("fileA","a");//打開或新建一個文本文件,只允許在文件末尾追寫
fp = fopen("fileA","at");//"a" = "at", 因爲默認打開text

fp = fopen("fileA","ab");//打開或新建一個二進制文件,只允許在文件末尾追寫

+字符,可以實現讀寫操作。

File *fp;
fp = fopen("fileA","r+");//打開文本文件,文件必須存在,允許讀寫
fp = fopen("fileA","rt+");//"r+" = "rt+", 因爲默認打開text

fp = fopen("fileA","w+");//創建文本文件, 若已存在則清空文件內容,允許讀寫
fp = fopen("fileA","rt+");//"w+" = "wt+", 因爲默認打開text

fp = fopen("fileA","rb+");//打開二進制文件,文件必須存在,允許讀寫
fp = fopen("fileA","wb+");//創建二進制文件, 若已存在則清空文件內容,允許讀寫

fp = fopen("fileA","a+");//打開或新建一個文本文件,可以讀,但只允許在文件末尾追寫
fp = fopen("fileA","at+");//"a+" = "at+", 因爲默認打開text
fp = fopen("fileA","ab+");//打開或新建一個二進制文件,可以讀,但只允許在文件末尾追寫

特別注意是:

  • 帶字符 r 的操作,必須有該文件存在,否則會返回空。
  • 帶字符 w 的操作,如果有原文件,該操作會刪除原文件,再新建文件,如果沒有原文件則直接新建文件。
  • 帶字符 a 的操作,如果有文件則會打開,沒有就會新建,不會清空內容,但只能在尾部寫

從上面看出,如果想要實現這樣的操作:如果有文件就讀文件,沒文件就創建文件,而且保證文件是可讀可寫的,這個時候好像沒有任何一個單一的fopen能滿足需求。
如果用fopen("name", "w+"),那麼如果有文件,也會被覆蓋掉,
如果用fopen("name", "r+"),那麼如果沒有文件,會返回false,所以實現上述功能需要結合兩個函數,如下所示:

if ((f = fopen(filename, "r+") == 0) //若存在文件,則直接打開
    f = fopen(filename, "w+"); //若不存在文件,則創建文件
if (f == 0)
    ...report error...

fread函數

參考鏈接:https://overiq.com/c-programming-101/fread-function-in-c/
The syntax of fread() function is this:

fread() function is the complementary of fwrite() function. fread() function is commonly used to read binary data. It accepts the same arguments as fwrite() function does.

Syntax: size_t fread(void *ptr, size_t size, size_t n, FILE *fp);

The ptr is the starting address of the memory block where data will be stored after reading from the file. The function reads n items from the file where each item occupies the number of bytes specified in the second argument. On success, it reads n items from the file and returns n. On error or end of the file, it returns a number less than n.

舉兩個簡單的例子:

//Example 1: Reading an array from the file
int arr[10];
fread(arr, sizeof(arr), 1, fp);

//Example 2: Reading the structure variable
struct student
{
    char name[10];
    int roll;
    float marks;
};
 
struct student student_1;
 
fread(&student_1, sizeof(student_1), 1, fp);

關於fread最值得注意的一點,fread讀取文件時,會自動保留當前的讀取位置,也就是說,不用自己去管讀取的位置在哪個字節,讀取了對應文件的部分後,會自動繼續往下讀取,關於這裏點,可以參考https://stackoverflow.com/questions/10696845/does-fread-move-the-file-pointer,具體舉個例子。

#include<stdio.h>
#include<stdlib.h>
 
struct employee
{
    char name[50];
    char designation[50];
    int age;
    float salary
} emp;
 
int main()
{
    FILE *fp;
    fp = fopen("employee.txt", "rb");
 
    if(fp == NULL)
    {
        printf("Error opening file\n");
        exit(1);
    }
 
    printf("Testing fread() function: \n\n");
    
 	//循環讀取,會自動往後讀,而不會反覆讀取文件的最前面的部分
    while( fread(&emp, sizeof(emp), 1, fp) == 1 )
    {
        printf("Name: %s \n", emp.name);
        printf("Designation: %s \n", emp.designation);
        printf("Age: %d \n", emp.age);
        printf("Salary: %.2f \n\n", emp.salary);
    }
 
    fclose(fp);
    return 0;
}

輸出結果:

Testing fread() function:
 
Name: Bob
Designation: Manager
Age: 29
Salary: 34000.00
 
Name: Jake
Designation: Developer
Age: 34
Salary: 56000.00
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章