microstation添加txt文件_C开发实战-文件操作
文件概述
文件幾乎無處不在,主要分為磁盤文件和設備文件,典型的磁盤文件有文本文件和二進制文件,磁盤文件存儲在外部存儲介質(例如磁盤,硬盤,U盤等等)需要加載到內存中才能使用。
無論是文本文件還是二進制文件在計算機內部都是以字節為單位,二進制的方式存儲。
- 文本文件存儲的是字符對應的ASCII碼值,例如文本字符的a在計算機內部就是以二進制01100001 即97存儲。當使用文本編輯器(例如Visual Studio Code)打開文本文件時,會將文本文件的二進制轉換成ASCII編碼對應的字符。
- 二進制文件存和取的是二進制數值,常見的二進制文件有圖片、音頻、視頻等等。二進制文件不能使用文本編輯器(例如Visual Studio Code)打開,圖片需要使用特定的軟件(例如Windows的照片瀏覽器)打開。
設備文件有標準輸入文件(stdin),標準輸出文件(stdout),標準錯誤(stderr)三個文件,設備文件在程序啟動時由系統默認打開,程序員無需調用fopen(stdin/stdout/stderr,"r+")函數打開這三個設備文件即可使用。
- stdin: 標準輸入,默認為當前終端(鍵盤),我們使用的scanf、getchar函數默認從此終端獲得數據。
- stdout:標準輸出,默認為當前終端(屏幕),我們使用的printf、puts函數默認輸出信息到此終端。
- stderr:標準出錯,默認為當前終端(屏幕),我們使用的perror函數默認輸出信息到此終端。
文件流指針
當打開文件時,系統內核會返回一個FILE結構體,該結構體有對文件操作的所有信息。
typedef struct{short level;//緩沖區"滿"或者"空"的程度 unsigned flags;//文件狀態標志 char fd;//文件描述符unsigned char hold;//如無緩沖區不讀取字符short bsize;//緩沖區的大小unsigned char *buffer;//數據緩沖區的位置 unsigned ar; //指針,當前的指向 unsigned istemp;//臨時文件,指示器short token;//用于有效性的檢查 }FILE;而當調用fopen()函數時,系統會返回這個FILE結構體的地址,即 FILE * p; ,當使用函數fputc('a',p)往文件寫入字符時,只需要傳遞文件流指針p即可。
文件流指針和之前的指針不同的是無法通過*p獲取文件內容。
文件的打開和關閉
文件的打開
C語言提供了fopen()函數用于打開文件,該函數的聲明位于stdio.h頭文件中,fopen()調用時需要兩個參數:路徑名和打開的方式,如果是當前路徑以./表示,Visual Studio2019 本地Windows調試器運行時源文件file_open_close.c的當前目錄是D:workspacecittimelinedotnetvs2019c-corec-core-advanced,打開方式可以是如下幾種方式
- r或rb 以只讀方式打開一個文本文件(不創建文件,若文件不存在則報錯)
- w或wb 以寫方式打開文件(如果文件存在則清空文件,文件不存在則創建一個文件)
- a或ab 以追加方式打開文件,在末尾添加內容,若文件不存在則創建文件
- r+或rb+ 以可讀、可寫的方式打開文件(不創建新文件)
- w+或wb+ 以可讀、可寫的方式打開文件(如果文件存在則清空文件,文件不存在則創建一個文件)
- a+或ab+ 以添加方式打開文件,打開文件并在末尾更改文件,若文件不存在則創建文件
其中w選項如果文件不存在會創建文件,但是如果文件有內容會清空。r選項文件不存在,則不創建文件。而b表示打開二進制文件。
fopen()打開文件成功后返回FILE*p結構體的地址,也標識了那個文件,操作指針就是操作那個文件。打開失敗返回NULL。
以只讀的方式打開當前路徑下的test.txt文件
#define _CRT_SECURE_NO_WARNINGS#include #include /* 以只讀方式打開當前目錄的test.txt文本文件*/void readonly_open_txt() {FILE* p_readonly = fopen("./test.txt", "r");if (p_readonly == NULL) {//追加錯誤提示前綴perror("readonly mode open file");return;}}/*文件的打開和關閉 fopen()函數打開方式說明 r或rb以只讀方式打開一個文本文件(不創建文件,若文件不存在則報錯) w或wb以寫方式打開文件(如果文件存在則清空文件,文件不存在則創建一個文件) a或ab以追加方式打開文件,在末尾添加內容,若文件不存在則創建文件 r+或rb+以可讀、可寫的方式打開文件(不創建新文件) w+或wb+以可讀、可寫的方式打開文件(如果文件存在則清空文件,文件不存在則創建一個文件) a+或ab+以添加方式打開文件,打開文件并在末尾更改文件,若文件不存在則創建文件@author liuguanglei 18601767221@163.com@wechat 18601767221@website ittimeline.net@version 2020/11/29*/int file_open_close_main(int argc, char* argv[]){readonly_open_txt();system("pause");return 0;}因為當前路徑下不存在test.txt文件,所以程序運行時會出現錯誤提示
以只寫的方式打開當前目錄下的test.txt文本文件,如果文件不存在則會創建文件,打開成功返回FILE *p_write
#define _CRT_SECURE_NO_WARNINGS#include #include /* 以只寫的方式打開當前目錄下的test.txt文本文件,如果文件不存在則會創建文件,打開成功返回FILE *p_write*/FILE* write_open_txt() { FILE* p_write = fopen("./test.txt", "w"); if (p_write == NULL) { perror("write mode open file"); return; } else { printf("open test.txt success!"); } return p_write;}/*文件的打開和關閉 fopen()函數打開方式說明 r或rb以只讀方式打開一個文本文件(不創建文件,若文件不存在則報錯) w或wb以寫方式打開文件(如果文件存在則清空文件,文件不存在則創建一個文件) a或ab以追加方式打開文件,在末尾添加內容,若文件不存在則創建文件 r+或rb+以可讀、可寫的方式打開文件(不創建新文件) w+或wb+以可讀、可寫的方式打開文件(如果文件存在則清空文件,文件不存在則創建一個文件) a+或ab+以添加方式打開文件,打開文件并在末尾更改文件,若文件不存在則創建文件@author liuguanglei 18601767221@163.com@wechat 18601767221@website ittimeline.net@version 2020/11/29*/int main(int argc, char* argv[]){FILE* p_write = write_open_txt();system("pause");return 0;}程序運行結果
以只寫方式打開時如果test.txt文件不存在,系統會創建文件
文件的關閉
C語言提供了fclose()函數用于關閉文件,該函數的聲明也位于stdio.h頭文件中,fclose()函數需要的參數就是打開文件返回的文件流指針,通常情況下文件打開后如果操作完成應該就要關閉。如果文件只打開而不關閉,會給程序造成異常。系統設置了一個應用程序只能打開1024個文件。
以只寫的方式打開當前系統路徑下的文本文件test.txt 后關閉文件
#define _CRT_SECURE_NO_WARNINGS#include #include /*以只寫的方式打開當前目錄下的test.txt文本文件,如果文件不存在則會創建文件,打開成功返回FILE *p_write*/FILE* write_open_txt() {FILE* p_write = fopen("./test.txt", "w");if (p_write == NULL) {perror("write mode open file");return;}return p_write;}/*文件的打開和關閉 fopen()函數打開方式說明 r或rb以只讀方式打開一個文本文件(不創建文件,若文件不存在則報錯) w或wb以寫方式打開文件(如果文件存在則清空文件,文件不存在則創建一個文件) a或ab以追加方式打開文件,在末尾添加內容,若文件不存在則創建文件 r+或rb+以可讀、可寫的方式打開文件(不創建新文件) w+或wb+以可讀、可寫的方式打開文件(如果文件存在則清空文件,文件不存在則創建一個文件) a+或ab+以添加方式打開文件,打開文件并在末尾更改文件,若文件不存在則創建文件@author liuguanglei 18601767221@163.com@wechat 18601767221@website ittimeline.net@version 2020/11/29*/int main(int argc, char* argv[]){FILE *p_write=write_open_txt();//關閉文件fclose(p_write);system("pause");return 0;}文件的順序讀寫
基于字符寫文件
C語言提供了fputc()函數實現寫入單個字符到文件中,該函數需要兩個參數:字符和文件流指針。寫入成功會返回寫入的字符,如果寫入失敗則返回-1
#define _CRT_SECURE_NO_WARNINGS#include #include /*以字符的方式寫入文件*/void write_file_char() {//以寫的方式打開當前目錄下的test.txt文件FILE* p_write = fopen("./test.txt","w");if (NULL==p_write) {perror("write mode open fail");return;}//將字符a寫入當前目錄下的test.txt文件char c=fputc('a', p_write);printf("寫入test.txt文本文件的字符內容是%c",c);}/*基于字符的文件寫操作@author liuguanglei 18601767221@163.com@wechat 18601767221@website ittimeline.net@version 2020/11/29*/int main(int argc, char* argv[]){write_file_char();system("pause");return 0;}程序運行結果
查看當前目錄D:workspacecittimelinedotnetvs2019c-corec-core-advanced 下test.txt文件的內容
需要注意的是fputc()函數在寫入字符前,默認會清空文件的內容,如果要是追加文件,將打開文件的打開方式改成追加即可。
//以追加的方式打開當前目錄下的test.txt文件FILE* p_append = fopen("./test.txt","a");而如果想要往文件追加寫入字符串,借助循環就可以搞定
#define _CRT_SECURE_NO_WARNINGS#include #include /*以追加的方式將字符寫入test.txt文本文件中*/void append_file_str() {FILE* p_append = fopen("./test.txt", "a");if (NULL == p_append) {perror("write mode open fail");return;}//以追加的方式將字符串hello world寫入test.txt文本文件中char buf[] = "hello world";int i = 0;while (buf[i] != 0) {fputc(buf[i], p_append);i++;}}/*基于字符的文件寫操作@author liuguanglei 18601767221@163.com@wechat 18601767221@website ittimeline.net@version 2020/11/29*/int main(int argc, char* argv[]){append_file_str();system("pause");return 0;}寫入字符串
基于字符讀文件
C語言提供了fgetc()函數實現基于字符從字符流指針中讀取文件,該函數的參數只需要傳遞文件流指針即可,讀取成功會返回讀取的字符,讀取失敗返回-1。
#define _CRT_SECURE_NO_WARNINGS#include #include char buf[128] = "";/*讀取指定路徑的文件并返回char**/char * read_text_by_char(char *path) {//以只讀的方式打開當前路徑下的test.txt文件FILE *p_readonly=fopen(path,"r");if (NULL==p_readonly) {perror("read file error");return NULL;}int i= 0;//EOF 表示-1 即當沒有讀取失敗時將讀取的值賦值給buf[i ]//fgetc()的返回值是-1表示失敗,當讀取的文件中有-1時,就會提前結束,因此不能使用EOFwhile ((buf[i++] = fgetc(p_readonly)) != EOF);return &buf;}/*基于字符讀取文件@author liuguanglei 18601767221@163.com@wechat 18601767221@website ittimeline.net@version 2020/11/29*/int main(int argc, char* argv[]){char *buffer=read_text_by_char("./test.txt");printf("test.txt content is %s", buffer);system("pause");return 0;}程序運行結果
fgetc()函數在基于字符讀取文件時,如果文件內容有-1這種數字,就不能使用EOF作為文件的結尾。
為了解決這個問題,C語言提供了feof()函數用于檢測是否讀到了文件的結尾。即判斷最后一次讀操作的內容不是當前位置的內容(上一個內容),該函數的返回值如果是0就表示沒有到文件結尾,如果是非0就表示到文件結尾。
#define _CRT_SECURE_NO_WARNINGS#include #include char buf[128] = "";/*使用feof()函數判斷文件是否讀取完畢,解決了fgetc()函數讀取-1字符的二進制返回-1時讀取就停止的問題*/char* read_text(char * path) {//以只讀的方式打開當前路徑下的test.txt文件FILE* p_readonly = fopen(path, "r");if (NULL == p_readonly) {perror("read file error");return NULL;}int i = 0;int pos = 0;do {buf[i] = fgetc(p_readonly);i++;pos = feof(p_readonly);// pos ==0 表示沒有到文件末尾} while (pos==0);return buf;}/*基于字符讀取文件@author liuguanglei 18601767221@163.com@wechat 18601767221@website ittimeline.net@version 2020/11/29*/int main(int argc, char* argv[]){char *buffer=read_text("./test.txt");printf("test.txt content is %s", buffer);system("pause");return 0;}基于字符文件的拷貝
文件的拷貝就是將一個文件創建一個副本。
而文本文件的拷貝的實現過程就是首先讀取一個文件,然后將讀取的文件內容寫入到待拷貝的文件中。
我這里封裝了一個函數 copy_text_file(char* source_path,char *target_path) ,只需要傳遞源文件和目標文件就可以實現文件的拷貝
#define _CRT_SECURE_NO_WARNINGS#include #include /*封裝一個文本文件的拷貝方法,傳遞兩個文件的路徑實現將source_path的文件內容拷貝到target_path*/void copy_text_file(char* source_path,char *target_path) {FILE* source = fopen(source_path,"r");if (NULL == source) {perror("open file error");}FILE* target = fopen(target_path,"w");if (NULL == target) {perror("open file target.txt error");}char ch = 0;while (1) {//讀取文件的內容ch=fgetc(source);//讀取到函數的末尾if (feof(source)) {break;}//將讀取的文件內容寫入到target文件指針fputc(ch, target);}//關閉文件fclose(target);fclose(source);}/*實現文件拷貝@author liuguanglei 18601767221@163.com@wechat 18601767221@website ittimeline.net@version 2020/11/29*/int main(int argc, char* argv[]){copy_text_file("./test.txt","./target.txt");system("pause");return 0;}程序運行結果
查看拷貝的源文件和目標文件的內容
但是copy_text_file(char* source_path,char *target_path)函數只能實現文本文件的拷貝,如果想要實現二進制文件(例如圖片)的拷貝,需要稍微改造下fopen()方法
#define _CRT_SECURE_NO_WARNINGS#include #include /*二進制文件的復制*/void copy_binary_file(char* source_path, char* target_path) {FILE* source = fopen(source_path, "rb");if (NULL == source) {perror("open file error");}FILE* target = fopen(target_path, "wb");if (NULL == target) {perror("open file target.txt error");}char ch = 0;while (1) {//讀取文件的內容ch = fgetc(source);//讀取到函數的末尾if (feof(source)) {break;}//將讀取的文件內容寫入到target文件指針fputc(ch, target);}//關閉文件fclose(target);fclose(source);}/*實現文件拷貝@author liuguanglei 18601767221@163.com@wechat 18601767221@website ittimeline.net@version 2020/11/29*/int main(int argc, char* argv[]){copy_binary_file("./20201129.jpg","./20201129_copy.jpg");system("pause");return 0;}程序運行結果
基于字符的文件查看
將指定的文件內容寫入到終端
#define _CRT_SECURE_NO_WARNINGS#include #include void cat_file(char* file_path) {//以只讀方式打開當前目錄的text_file_cat.c文件FILE *p=fopen(file_path,"r");if (NULL==p) {perror("file read error");return;}char ch = 0;while (1) {//讀取指定的內容ch = fgetc(p);//如果讀到文件末尾if (feof(p)) {break;}//將讀取的文件內容寫入到終端 //stdout表示終端的文件流指針//printf()底層會調用fputc()fputc(ch,stdout);}//關閉文件fclose(p);}/*文本文件查看@author liuguanglei 18601767221@163.com@wechat 18601767221@website ittimeline.net@version 2020/11/29*/int main(int argc, char* argv[]){cat_file("text_file_cat.c");return 0;}程序運行結果
基于行寫文件
C語言提供了fputs(const char*str,FILE *stream)函數用于將字符串寫入到指定的文件,其中str是待寫入文件的字符串地址,stream表示文件流指針,字符串結束符 '0' 停止寫入,寫入成功返回0,寫入失敗返回-1。
#define _CRT_SECURE_NO_WARNINGS#include #include /*fputs()寫入字符串到指定的文件@author liuguanglei 18601767221@163.com@wechat 18601767221@website ittimeline.net@version 2020/11/29*/int main(int argc, char* argv[]){//以只寫的方式打開當前路徑下的test.txtFILE* p = fopen("test.txt","w");if (NULL==p) {perror("open file fail");}char buf[] = "I will see you again0again ";//將字符串I will see you again 寫入到test.txt文件中//遇到0停止寫入int result = fputs(buf,p);if (result==0) {printf("寫入數據成功");}else {printf("寫入數據失敗");}system("pause");return 0;}程序運行結果
基于行讀文件
C語言提供了fgets(char* str, int size ,FILE *stream)函數用于從文件讀取字符串,其中str用于保存讀取的內容,而size是指定最大讀取字符串的長度(size-1),stream表示文件流指針。fgets()函數遇到會結束。
讀取成功則返回讀取的字符串,讀取到文件末尾或則失敗則返回NULL。需要注意的是 fgets()函數只能操作字符串,不能操作二進制文件。
程序運行結果
基于fputs()函數和fgets()函數實現的文本文件拷貝
#define _CRT_SECURE_NO_WARNINGS#include #include #include /*基于fputs()和fgets()函數實現的文件拷貝 只能支持文本文件,因為遇到0會停止讀寫*/void copy_by_fgets_fputs(char * source_path,char *target_path) {FILE* source = fopen(source_path,"r");if (NULL==source) {perror("open file fail");return;}FILE* target = fopen(target_path,"w");if (NULL == target) {perror("open file fail");return;}char* p = NULL;//循環多少次,buf就可以使用多少次char buf[1024] = "";while (1) {memset(buf, 0, sizeof(buf));p = fgets(buf, sizeof(buf), source);//讀取結束if (p==NULL) {break;}//將讀取的內容寫入到targetfputs(buf, target);}//fclose(target);fclose(source);}/*基于fputs()和fgets()函數實現的文件內容拷貝@author liuguanglei 18601767221@163.com@wechat 18601767221@website ittimeline.net@version 2020/11/29*/int main(int argc, char* argv[]){copy_by_fgets_fputs("./test.txt","./copy_of.txt");system("pause");return 0;}程序運行結果
基于文件讀寫實現隨機生成表達式并完成四則運算
首先定義一個宏,用于描述生成表達式的數量
//表達式生成的數量#define EXPRESSION_NUM 10由于生產表達式,需要讀寫文件,在讀寫文件之前,需要打開文件,因此封裝一個打開文件的函數,該函數需要一個參數:打開方式
而FILE_PATH 也是宏定義的文件路徑#define FILE_PATH "expression_calc.txt",算術運算表達式就是存儲在該文件中。
然后實現生成表達式的函數。以及將生成的表達式寫入文件中。
這其中表達式的操作數和運算符都是是隨機生成的,需要借助srand()函數和rand()函數。
然后還要使用sprintf()函數組包生成表達式。
然后實現讀取文件后計算表達式,并將表達式的結果寫入FILE_PATH中。
/*計算表達式的結果并寫入文件*/void calc_expression_write_file() {FILE* fp = open_file("r");//第一個操作數int left = 0;//第二個操作數int right = 0;//運算符char operator=0;//運算的結果int result = 0;//讀取的單個表達式(未計算)char buf[128] = "";//單個表達式(已經計算結果的)char singleton_expression[128] = "";//所有的表達式char all_expression[100][128] = { 0 };//讀取一行表達式的指針char* p = NULL;int i = 0;printf("生成的表達式列表");while (1) {//每次讀取一行p = fgets(buf, sizeof(buf), fp);if (p == NULL) {break;}//將讀取的內容buf 解析到left, operator,right變量中sscanf(buf, "%d%c%d", &left, &operator,&right);//根據運算的符來進行運算并保存運算的結果switch (operator) {case '+':result = left + right;break;case '-':result = left - right;break;case '*':result = left * right;break;case '/':result = left + right;break;}//2+3=5//將表達式以及計算的結果寫入all_expression二維數組中sprintf(all_expression[i], "%d%c%d=%d", left, operator,right, result);printf("%s ", all_expression[i]);i++;}//關閉文件fclose(fp);//FILE *n_fp = open_file("w");for (int j = 0; j < i; j++) {int result =fputs(all_expression[j], n_fp);if (result==0) {printf("寫入%s到文件%s成功", all_expression[j],FILE_PATH);}else {printf("寫入%s到文件%s失敗", all_expression[j], FILE_PATH);}}fclose(n_fp);}最后在main函數中依次調用這兩個函數并運行即可
#define _CRT_SECURE_NO_WARNINGS#include#include#include#include //表達式生成的數量#define EXPRESSION_NUM 10#define FILE_PATH "expression_calc.txt"/*基于文件讀寫實現隨機生成表達式并完成四則運算@author liuguanglei 18601767221@163.com@wechat 18601767221@website ittimeline.net@version 2020/11/29*/int main(int argc, char* argv[]){generator_expression_write_file();calc_expression_write_file();system("pause");return 0;}程序運行結果
程序運行結果
基于指定格式寫文件
C語言提供了fprintf(FILE * stream, const char * format, ...)函數用于將數據按照指定的格式寫入到指定的文件中,其中stream表示文件流指針,而format就是數據的格式,...表示需要組裝的數據列表。
fprintf()函數寫入成功則會返回實際寫入的字符個數,如果寫入失敗則返回-1。
程序運行結果
程序運行結果
基于指定格式讀文件
C語言提供了fscanf(FILE * stream, const char * format, ...);函數用于從文件中按照指定的格式來讀取數據,讀取成功返回成功轉換參數的個數,失敗返回-1。
#define _CRT_SECURE_NO_WARNINGS#include #include /*使用fscanf()從文件中讀取指定格式的數據@author liuguanglei 18601767221@163.com@wechat 18601767221@website ittimeline.net@version 2020/11/29*/int main(int argc, char* argv[]){int year = 0;int month = 0;int day = 0;FILE* fp = fopen("./date.txt", "r");if (NULL == fp) {perror("read file fail");return -1;}//從date.txt文件中讀取日期并賦值給year,month,dayfscanf(fp, "%d-%d-%d", &year, &month, &day);printf("year = %d",year);printf("month = %d", month);printf("day = %d", day);system("pause");return 0;}讀取的文件內容
程序運行結果
基于塊寫文件
在讀寫大文件時需要基于塊來讀寫文件,C語言提供了fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream);函數來基于塊寫文件,其中ptr表示寫入文件數據的地址,size表示寫入文件內容的大小,nmemb表示寫入文件的塊數,寫入文件的總大小為szie * nmemb,stream表示已經打開的文件流指針。寫入成功則返實際成功寫入文件數據的塊數目,該值和nmemb相等。
將結構體數組user_array以塊的形式寫入fwrite.txt文件
#define _CRT_SECURE_NO_WARNINGS#include #include //定義一個結構體user,別名是userstypedef struct user {int id;char name[16];}users;/*fwrite()函數:基于塊寫文件@author liuguanglei 18601767221@163.com@wechat 18601767221@website ittimeline.net@version 2020/11/29*/int main(int argc, char* argv[]){//初始化一個結構體數組users user_array[3] = { {1,"tony"},{2,"mengmeng"},{3,"xiaohuihui"} };FILE* fp = fopen("fwrite.txt","w");if (NULL==fp) {perror("open file fail");return -1;}//fwrite()第二個參數寫1,返回值剛好是寫入文件的字節數int byte_size=fwrite(user_array, 1, sizeof(user_array), fp);printf("寫入文件的字節數是%d",byte_size);system("pause");return 0;}基于塊讀文件
C語言提供了size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);函數用于基于塊的方式讀取文件內容
其中ptr:存放讀取出來數據的內存空間,size: size_t 為 unsigned int類型,此參數指定讀取文件內容的塊數據大小,nmemb:讀取文件的塊數,讀取文件數據總大小為:size * nmemb,stream:已經打開的文件指針
如果讀取成功則返回實際成功讀取到內容的塊數,如果此值比nmemb小,但大于0,說明讀到文件的結尾。否則失敗返回0
實現讀取fwrite.txt文件的內容,由于該文件的內容是一個結構體數組,因此需要在頭文件user.h中定義一個通用的結構體,其他的源文件使用該結構體時包含#include "user.h"即可
#pragma once//定義一個結構體user,別名是userstypedef struct user {int id;char name[16];}users;然后使用fread()函數讀取文件內容并存儲到結構體數組中,然后遍歷結構體數組的內容,顯示在終端上。
#define _CRT_SECURE_NO_WARNINGS#include #include #include "user.h"#include /*fread()基于塊的方式讀取文件@author liuguanglei 18601767221@163.com@wechat 18601767221@website ittimeline.net@version 2020/11/29*/int main(int argc, char* argv[]){users user_array[3];//將數組清零memset(user_array, 0, sizeof(user_array));int size = sizeof(user_array) / sizeof(user_array[0]);FILE* fp = fopen("./fwrite.txt","r");//一次性讀到user_arrayfread(&user_array, 1, sizeof(user_array), fp);for (int i = 0; i < size;i++) {//從fp讀取一個結構體users并賦值給&user_array[i]//fread(&user_array[i], 1, sizeof(users), fp);printf("id = %d name = %s ",user_array[i].id,user_array[i].name);}system("pause");return 0;}程序運行效果
文件的隨機讀寫
之前介紹的讀寫文件函數都是順序讀寫的。
C語言提供了fseek(FILE *stream, long offset, int whence) 函數實現移動文件流(文件光標)的讀寫位置實現隨機讀寫。
- fseek(fp,6,SEEK_SET)表示光標相對于開頭向后移動6個字節
- fseek(fp,0,SEEK_SET)表示光標移動至開頭
- fseek(fp,4,SEEK_CUR)表示光標相對當后移動4個字節
- fseek(fp,-4,SEEK_CUR)表示光標相對當前移動4個字節
- fseek(fp,4,SEEK_END)表示光標相對末尾往后移動4個字節
除此以外C語言還提供了rewind(fp)函數將光標移到開頭,等價于fseek(fp,0,SEEK_SET),ftell(fp)函數可以獲取文件流(文件光標)的讀寫位置。
#define _CRT_SECURE_NO_WARNINGS#include #include #include /*fseek()隨機讀寫@author liuguanglei 18601767221@163.com@wechat 18601767221@website ittimeline.net@version 2020/11/29*/int main(int argc, char* argv[]){FILE* fp = fopen("fseek.txt", "w");if (NULL == fp) {perror("open file fail");return 0;}//往fseek.txt文件寫入this is test content 此時光標默認在末尾fputs("this is test content", fp);//移動光標到首部fseek(fp, 0, SEEK_SET);//寫入seek到fseek.txt,此時文件內容是seek is test contentfputs("seek", fp);//移動光標到倒數第五個字節fseek(fp,-5,SEEK_END);//在倒數第五個字節的光標寫入again,此時文件內容是seek is test coagainfputs("again", fp);//將光標移到開頭//rewind(fp);//將光標移到末尾fseek(fp, 0, SEEK_END); //計算末尾到開頭的字節數int byte_size=ftell(fp);printf("byte_size=%d",byte_size);int count = ftell(fp);system("pause");return 0;}程序運行結果
獲取文件信息
C語言提供了stat(const char *path, struct stat *buf)函數用于獲取文件信息,如果獲取成功返回0,獲取失敗則返回-1。stat()函數可以判斷該文件存不存在獲取文件狀態。
在使用該函數前需要包含兩個系統路徑下的頭文件:sys/types.h和sys/stat.h
#define _CRT_SECURE_NO_WARNINGS#include #include #include #include /*stat()函數獲取文件狀態@author liuguanglei 18601767221@163.com@wechat 18601767221@website ittimeline.net@version 2020/11/29*/int main(int argc, char* argv[]){//定義stat結構體struct stat file_info;int info= stat("fwrite.txt",&file_info);//文件不存在if (info<0) {//打印輸出提示信息printf("file not found ");}else {printf("獲取文件信息: 文件大小是%d字節 ", file_info.st_size);}system("pause");return 0;}程序運行結果
文件刪除和重命名
文件刪除
C語言提供了庫函數remove(const char *path)來刪除一個文件,參數需要一個文件的路徑,刪除成功返回0,刪除失敗返回-1
#define _CRT_SECURE_NO_WARNINGS#include #include /*文件刪除@author liuguanglei 18601767221@163.com@wechat 18601767221@website ittimeline.net@version 2020/11/29*/int main(int argc, char* argv[]){//刪除當前路徑下的fwrite.txt文件int flag=remove("fwrite.txt");if (flag==0) {printf("刪除成功");}else {printf("刪除失敗");}system("pause");return 0;}程序運行結果
文件重命名
C語言提供了rename(const char *oldpath, const char *newpath)函數實現文件的重命名,該函數需要兩個文件的完整路徑
#define _CRT_SECURE_NO_WARNINGS#include #include /*rename()函數實現文件的重命名@author liuguanglei 18601767221@163.com@wechat 18601767221@website ittimeline.net@version 2020/11/29*/int main(int argc, char* argv[]){//文件重命名rename("fseek.txt","fseek_rename.txt");system("pause");return 0;}程序運行結果
Linux和Windows文本文件的區別
- Windows字符串中帶時存取的是
- Linux中字符串帶時存取的是
如果把Windows的文本文件傳到Linux系統上時使用編輯器打開會多了一個。而Linux的文本文件到Windows下就沒有換行。
文件緩沖區
緩沖區本質就是內存中的一塊臨時空間,
當寫入文件時,庫函數會去調用內核提供的系統調用,例如fwrite()函數最終會調用write()系統調用。如果是大量頻繁的寫操作,會從用戶空間切換到內核空間,上下文的切換會導致程序效率非常低。
因此引入了文件的緩沖區,當緩沖區滿了才會一次性寫入文件,或者有特殊場景可以調用fflush()強制刷新緩沖區,也就是將緩沖區的內容寫入文件,或者程序正常退出(關閉Visual Studio的終端)時也會將緩沖區的文件寫入磁盤文件。
緩沖區
刷新緩沖區的兩種編碼實現
#define _CRT_SECURE_NO_WARNINGS#include #include #include /*文件緩沖區@author liuguanglei 18601767221@163.com@wechat 18601767221@website ittimeline.net@version 2020/11/29*/int main(int argc, char* argv[]){FILE* fp = fopen("data.txt","w");if (NULL==fp) {perror("open file fail");return -1;}//當不關閉終端時data.txt文件沒有內容fputs("this is test content ",fp);//可以調用fflush()函數實現強制刷新緩沖區的內容到data.txt;fflush(fp);//也可以將緩沖區寫滿char buf[1024] = "";//寫入1M的1for (int i = 0; i < 1024;i++) {memset(buf, '1', sizeof(buf));fwrite(buf, 1, sizeof(buf), fp);}system("pause");return 0;}而Windows下的stdout 是沒有緩沖區的,即使用printf()函數打印數據到終端時不會進入緩沖區,直接寫入到終端上。而Linux下的stdout文件是有緩沖區的。
Windows下標準輸入(stdin) 不能調用fflush()強制刷新。
總結
以上是生活随笔為你收集整理的microstation添加txt文件_C开发实战-文件操作的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: mysql查看用户名_Mysql创建数据
- 下一篇: java调用 restapi 乱码_Ja