天天看點

用c語言寫庫檔案,利用C/C++庫函數讀寫檔案的基本用法

使用檔案方式

含義

"r"(隻讀)

為輸入打開一個文本檔案

"w"(隻寫)

為輸出打開一個文本檔案

"a"(追加)

為追加打開一個文本檔案

"rb"(隻讀)

為輸入打開一個二進制檔案

"wb"(隻寫)

為輸出打開一個二進制檔案

"ab"(追加)

為追加打開一個二進制檔案

"r+"(讀寫)

為讀/寫打開一個文本檔案

"w+"(讀寫)

為讀/寫建立一個文本檔案

"a+"(讀寫)

為讀/寫打開一個文本檔案

"rb+"(讀寫)

為讀/寫打開一個二進制檔案

"wb+"(讀寫)

為讀/寫建立一個二進制檔案

"ab+"(讀寫)

為讀/寫打開一個二進制檔案

說明: 1. 使用"r"時,如果檔案不存在,則出錯。

2. 使用"w"時,如果沒有檔案,則建立一個新檔案。

3. 使用"a"時,如果希望向檔案尾添加資料,則該檔案必須存在,否則出錯。

4. "r+","w+","a+"都是可以輸入和輸出資料,但必須遵守上述3點

5. 操作二進制檔案時,加上"b"字元,且二進制檔案對換行符不會進行轉換,而文本檔案會将換行符轉換為回車和換行兩個字元。

檔案的關閉(fclose函數)

在使用完一個檔案後,若不關閉則會造成系統資源洩漏。使用fclose()關閉檔案即可,原型為 int fclose(FILE* fp)。使用:fclose(fp); flose()傳回0時為順利關閉檔案,否則傳回EOF(-1)。

檔案的讀寫1) fputc(), fgetc()分别為從檔案流中寫和讀一個字元,原型分别如下:

寫:int fputc(int c, FILE* fp);      讀:int fgetc(FILE* fp); 失敗時均傳回EOF

2) fputs(), fgets()分别為從檔案流中寫和讀一個字元串,原型分别如下:

寫:int fputs(const char* str, FILE* fp);  例如: fputs("I love this game!", fp);

讀:char* fgets(char* str, int n, FILE* fp); 從流中讀取n-1個字元或讀完一行,參數str用于接收讀取的字元串。注意當讀取一行時,不包括行尾的'\n'字元。

3) fseek() 一般用于二進制模式打開的檔案中,功能是定位到流中指定的位置。原型如下:

int fseek(FILE* fp, lont offset, int whence); 參數offset是移動的字元數,whence是移動的基準,取值是:

SEEK_SET 0 //檔案開頭

SEEK_CUR 1 //目前讀寫的位置

SEEK_END 2 //檔案尾部

4) fprintf(),fscanf()是将資料按格式輸出輸入到檔案流中,用法類似printf()和scanf()。原型分别如下:

int fprintf(FILE* fp, const char* format, ...); 它與printf()不同的就是将資料寫到了檔案流中,而不是控制台罷了。

int fscanf(FILE* fp, cosnt char* format, ...); 從檔案流中按格式讀取,與scanf()不同的就是資料是從檔案流中讀取而已。

例如: fprintf(fp, "count=%d", 5);         fscanf(fp, "%d", &x);

5) feof()是檢測是否已到檔案尾,是傳回真,否則傳回0,原型是 int feof(FILE* fp);

6) rewind() 則是把目前的讀寫位置回到檔案開始,相當于 fseek(fp, 0L, SEEK_SET); 原型: void rewind(FILE* fp);

7) remove() 删除檔案,原型: int remove(const char* filename);  參數為要删除的檔案名,成功則傳回0;

8) fread(), fwrite() 它們相當于可将一塊的資料讀出或寫入,相當的友善。原型如下:

size_t fread(void* ptr, size_t size, size_t n, FILE* fp); 從流中讀指定個數的字元,size是每塊的位元組婁,n則是讀取的塊數。

size_t fwrite(const void* ptr, size_t size, size_t n, FILE* fp); 類似的是向檔案流中寫入n塊size位元組數的資料。可以看到資料指針為void*型,即可以使用任何類型的指針來替換。例如:

現在一個結構體: struct student_t{char name[16]; int id; int age;}; 建立三個學生的資料并指派:struct student_t stu[3];

這時,當我們找開檔案後(一般是進制模式),可以調用fwrite()将三個學生的資料都寫入到檔案中,兩種方式:

for(int i = 0; i < 3; ++i)

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

或者:fwrite(stu, sizeof(struct student_t), 3, fp);

些時,我們調用fread()函數便可很輕松的将剛才寫入的3個學生的資料讀取出來:

struct student_t stus[3];

for(int i = 0; i < 3; ++i)

fread(&stus[i], sizeof(struct student_t), 1, fp);

或者:fread(stus, sizeof(struct student_t), 3, fp); 這樣便可将三個學生的資料讀入到stus變量中了(有木有很友善呐)

注意:如果你發現使用fread()讀取之後,最後一個學生讀取的資料不完全,可能是由于你沒有使用二進制模式打開的原因。

9) 最後是tmpfile()和tmpnam(),前者為生成一個臨時檔案,後者為生成一個唯一的檔案名,具體使用在此不介紹了。

二、使用C++中的fstream檔案流操作類進行檔案的讀寫

使用fstream操作檔案與使用C庫函數類似,隻不過fstream為面向對象方式,或多了上些C++的特性。首先,這裡大概有三個流:

fstream為檔案輸入輸出流,ifstream為輸入檔案流,ofstream為輸出檔案流,它們與ostream不同的就流的目的地為檔案,而不是控制台。這裡隻介紹與上述的一些不同點:

1. 打開檔案,如可以是 ifstream input_file("file2.txt"); 這樣将會以預設方式打開file2.txt檔案并進行讀取。也可使用open()方式打開一個檔案,并指定打開方式,例如:

ifstream input_file;

input_file.open("file2.txt", ios::binary);

打開後,可以使用is_open()檢測是否打開成功:

if(input_file.is_open()){},然後可以使用流操作符向檔案寫資料了,例如:

input_file << "this is a test line";

input_file << "another info";

另外,這裡的檔案打開方式在ios空間下:

ios::app 添加到檔案尾

ios::ate 把檔案标志放在末尾而非起始。

ios::trunc 預設. 截斷并覆寫檔案。

ios::nocreate 檔案不存在也不建立。

ios::noreplace 檔案存在則失敗。

ofstream使用方式類似,讀取一行資料可以使用getline(buf, count), 類型于fgets()。fstream類還提供一個很多其它方法,如fclose()為關閉檔案,eof()用于檢測狀态是否已經到了檔案末尾。

這裡還有兩個類似于上述的fread()和fwrite()函數,是read(), write(),功能和用法類似類似,例如:

output_file.write((const char*)stu, 3 * sizeof(struct student_t));

input_file.read((char*)stus, 3 * sizeof(struct student_t));

注意,這裡也需要使用二進制模式打開,否則read的時候最後的上些資料讀不完全。調用上面兩個函數後可以使用bad()來檢測檔案流對象是否錯誤,例如,if(input_file.bad()){printf("error when read file\n"); return;},最後input_file.close()即可。

最後,C/C++檔案的操作并不複雜,多使用幾次便可熟練掌握,需要注意的就是檔案的打開方式,和當用同一個檔案指針進行又讀又寫時,注意檔案指針位置的移動。