[源碼下載]
作者:webabcd
介紹
不可或缺 Windows Native 之 C 語言
示例
cFile.h
#ifndef _MYHEAD_FILE_ #define _MYHEAD_FILE_ #ifdef __cplusplus extern "C" #endif char *demo_cFile(char *rootPath); #endif
cFile.c
/* * 文件 * * 從用戶角度講,文件可分為普通文件和設備文件兩種 * 1、普通文件是指保存在磁盤或其它外部介質上的一段數據 * 2、設備文件是指與主機相聯的各種外部設備,操作系統會把各種外部設備也看作是一個文件來進行管理。比如:通常把顯示器定義為標准輸出文件,鍵盤定義為標准輸入文件 * * 從文件編碼的方式來看,文件可分為 ASCII 碼文件(文本文件)和二進制文件 * 1、ASCII 文件也稱為文本文件,這種文件在磁盤中存放時每個字符對應一個字節,用於存放對應的 ASCII 碼。比如:字符串 1234567 按字符存放成文本文件,占用 7 個字節 * 2、二進制文件是按二進制的編碼方式來存放文件的。比如:數字 1234567 按整型存放成二進制文件,占用 4 個字節 * * 關於 mkdir(make directory) - 創建目錄,rmdir(remove directory) - 刪除目錄 之類的函數,以後再寫 * * * 注:EOF(end of file) - 文件的結束標志 */ #include "pch.h" #include "cFile.h" #include "cHelper.h" void file_demo1(); void file_demo2(); void file_demo3(); void file_demo4(); void file_demo5(); char *_rootPath; char *demo_cFile(char *rootPath) { _rootPath = rootPath; // 寫入文本文件 file_demo1(); // 讀取文本文件 file_demo2(); // 以格式化的方式讀寫文本文件 file_demo3(); // 讀寫二進制文件 file_demo4(); // 文件的內部定位(隨機讀寫,即任意位置讀寫) file_demo5(); return str_concat2("演示文件的保存路徑:", rootPath); } // 寫入文本文件 void file_demo1() { // 文件指針 - 指向文件的指針(FILE *指針變量標識符) // 需要訪問的文件路徑 char *fileName = str_concat2(_rootPath, "\\c_file_demo1.txt"); // fopen - 用指定的方式打開指定路徑的文件,並返回文件指針(FILE 是由系統定義的結構體,fp 是指向 FILE 的文件指針) FILE *fp = fopen(fileName, "wt+"); // 第 2 個參數是文件打開方式,其說明參見後面的注釋 if (fp == NULL) { // 如果 fopen 返回空指針,則說明文件打開失敗(errno 中保存著最近一次的錯誤) int errNum = errno; // 關於 errno 的預定義參見 errno.h } else { // rewind - 讓指定的文件指針所指文件的內部位置指針移到文件頭 rewind(fp); // fputc - 向指定的文件寫入字符(這裡的 EOF 代表寫入失敗) if (fputc('w', fp) == EOF) { // ferror - 檢查文件在讀寫時是否出錯,返回值為 0 表示正常,否則表示有錯 int errNum = ferror(fp); // 關於 errno 的預定義參見 errno.h // clearerr - 清除出錯標志,使它為 0 值。 clearerr(fp); } // fputs - 向指定的文件寫入字符串(這裡的 EOF 代表寫入失敗) if (fputs("ebabcd\nwanglei", fp) == EOF) { // ferror - 檢查文件在讀寫時是否出錯,返回值為 0 表示正常,否則表示有錯 int errNum = ferror(fp); // 關於 errno 的預定義參見 errno.h // clearerr - 清除出錯標志,使它為 0 值。 clearerr(fp); } // fclose - 打開文件後,必須要用 fclose 關閉文件,返回 0 則說明文件正常關閉了 int fcloseResult = fclose(fp); } free(fileName); } // 讀取文本文件 void file_demo2() { char *fileName = str_concat2(_rootPath, "\\c_file_demo1.txt"); FILE *fp = fopen(fileName, "rt"); if (fp == NULL) { int errNum = errno; } else { rewind(fp); // fgetc - 一個字符一個字符地讀,如遇到 EOF 則文件讀完或出錯(每個文件末尾都有結束標志 - EOF) char ch = fgetc(fp); while (ch != EOF) { // 每讀一個字符,則內部位置指針會向後移動一個字節 ch = fgetc(fp); } // feof - 檢查文件是否結束(即內部位置指針是否指向 EOF),如結束,則返回非零值,否則返回 0 int isEnd = feof(fp); // 非零值 rewind(fp); // feof - 檢查文件是否結束(即內部位置指針是否指向 EOF),如結束,則返回非零值,否則返回 0 isEnd = feof(fp); // 0 /* * fgets(str, n, fp) - 讀取字符串函數 * str - 字符數組名,由於保存讀取到的字符串 * n - 讀出 n-1 個字符並送入字符數組 str 中,然後在結尾加'\0'(在讀出 n-1 個字符之前,如遇到了換行符或 EOF,則讀取結束) * fp - 文件指針 */ char str[32]; while (fgets(str, 32, fp) != NULL) { // 本例會循環 2 次 // 第 1 次 str 的結果為:webabcd\n // 第 2 次 str 的結果為:wanglei } fclose(fp); } free(fileName); } // 以格式化的方式讀寫文本文件 void file_demo3() { char *fileName = str_concat2(_rootPath, "\\c_file_demo2.txt"); FILE *fp = fopen(fileName, "wt+"); if (fp == NULL) { int errNum = errno; } else { // fprintf(file print formatted) - 以格式化的方式寫入字符串(返回值為寫入的字節數) int fprintfResult = fprintf(fp, "%s %d %d\n", "webabcd", 100, 20); // 15 rewind(fp); int num; int age; char name[32]; // fscanf(file scan formatted) - 以格式化的方式讀取字符串(返回值為讀取的成員數) int fscanfResult = fscanf(fp, "%s %d %d\n", name, &num, &age); // 3 fclose(fp); } free(fileName); } // 讀寫二進制文件 void file_demo4() { struct employee { int num; char name[32]; } w[2] = { { 100, "wanglei" }, { 200, "webabcd" } }, r[2], *ww, *rr; ww = w; rr = r; char *fileName = str_concat2(_rootPath, "\\c_file_demo3.b"); FILE *fp = fopen(fileName, "wt+"); if (fp == NULL) { int errNum = errno; } else { /* * fwrite(buffer, size, count, fp) - 寫入二進制數據(返回值為成功寫入的數據塊數) * buffer - 需要寫入的數據的指針 * size - 每一個數據塊的字節數 * count - 需要寫入的數據塊數 * fp - 文件指針 */ int fwriteResult = fwrite(ww, sizeof(struct employee), 2, fp); // 2 rewind(fp); /* * fread(buffer, size, count, fp) - 讀取二進制數據(返回值為成功讀取的數據塊數) * buffer - 需要保存讀取數據的指針 * size - 每一個數據塊的字節數 * count - 需要讀取的數據塊數 * fp - 文件指針 */ int freadResult = fread(rr, sizeof(struct employee), 2, fp); fclose(fp); } free(fileName); } // 文件的內部定位(隨機讀寫,即任意位置讀寫) void file_demo5() { struct employee { int num; char name[32]; } w[2] = { { 100, "wanglei" }, { 200, "webabcd" } }, r[1], *ww, *rr; ww = w; rr = r; char *fileName = str_concat2(_rootPath, "\\c_file_demo4.b"); FILE *fp = fopen(fileName, "wt+"); if (fp == NULL) { int errNum = errno; } else { int fwriteResult = fwrite(ww, sizeof(struct employee), 2, fp); /* * rewind(fp) - 把文件內部位置指針移到文件頭 * fp - 文件指針 */ rewind(fp); /* * fseek(fp, offset, origin) - 移動文件內部位置指針 * fp - 文件指針 * offset - 相對於 origin 的位移字節數(長整形,如果用常量的話記得加“L”) * origin - 位移起始點 * SEEK_SET(0) - 文件頭 * SEEK_CUR(1) - 當前位置 * SEEK_END(2) - 文件尾 */ fseek(fp, sizeof(struct employee), SEEK_SET); int freadResult = fread(rr, sizeof(struct employee), 1, fp); // 200, "webabcd" fclose(fp); } free(fileName); } /* * 關於文件打開方式的說明,即 fopen 的第 2 個參數 * rt 只讀打開一個文本文件,只允許讀數據 * wt 只寫打開或建立一個文本文件,只允許寫數據 * at 追加打開一個文本文件,並在文件末尾寫數據 * rb 只讀打開一個二進制文件,只允許讀數據 * wb 只寫打開或建立一個二進制文件,只允許寫數據 * ab 追加打開一個二進制文件,並在文件末尾寫數據 * rt+ 讀寫打開一個文本文件,允許讀和寫 * wt+ 讀寫打開或建立一個文本文件,允許讀寫 * at+ 讀寫打開一個文本文件,允許讀,或在文件末追加數據 * rb+ 讀寫打開一個二進制文件,允許讀和寫 * wb+ 讀寫打開或建立一個二進制文件,允許讀和寫 * ab+ 讀寫打開一個二進制文件,允許讀,或在文件末追加數據 * * 關於上面字符的說明 * r(read) 讀 * w(write) 寫 * a(append) 追加 * t(text) 文本文件,可省略不寫 * b(banary) 二進制文件 * + 讀和寫 */
OK
[源碼下載]