C語言基礎(chǔ)文件操作方式超全詳解建議收藏
什么是文件
磁盤上的文件是文件。
在程序設(shè)計中,我們一般讀的文件有兩種:程序文件 和 數(shù)據(jù)文件
程序文件包括源程序文件(后綴為.c)、目標文件(win下后綴為 .obj)、可執(zhí)行文件(win下環(huán)境后綴為.exe)
數(shù)據(jù)文件:文件的內(nèi)容不一定是程序,而是運行時讀寫的程序,比如程序運行需要從中讀取數(shù)據(jù)的文件,或者輸出內(nèi)容的文件。
文件名
一個文件要有一個唯一的文件標識,以便于用戶識別與引用。
文件名包含3部分:文件路徑+文件名主干+文件后綴
c:\code\test.txt
文件類型
文本文件:肉眼看得懂的東西
二進制文件:數(shù)據(jù)在內(nèi)存中中以二進制形式存儲,如果不加轉(zhuǎn)換的輸出到外存,就是二進制文件。
如果要求在外存上以ASCII碼的形式存儲,則需要在存儲前轉(zhuǎn)換,以ASCII字符(對應(yīng)ASCII的值)的形式存儲的文件就是文本文件。
文件指針
文件類型指針(文件指針)
每個被使用的文件都在內(nèi)存中開辟一個相應(yīng)的文件信息區(qū),用來存放文件的相關(guān)信息(如文件名字,文件狀態(tài),文件當前的位置)。這些信息是保存在一個結(jié)構(gòu)體變量中的。該結(jié)構(gòu)體類型是有系統(tǒng)聲明的,取名為FILE
.
vs2019編譯環(huán)境中提供的 stdio.h
頭文件中有以下的文件類型聲明。
#ifndef _FILE_DEFINED #define _FILE_DEFINED typedef struct _iobuf { void* _Placeholder; } FILE; #endif
不同C編譯器的FILE類型包含內(nèi)容大同小異。
每當打開一個文件的時候,系統(tǒng)會根據(jù)文件的情況自動創(chuàng)建一個FILE結(jié)構(gòu)的變量,并填充其中的信息,使用者不必關(guān)心細節(jié)。
一般都是通過FILE的指針來維護這個FILE結(jié)構(gòu)的變量。
FILE *pf;
定義pf是一個指向FILE類型數(shù)據(jù)的指針變量,可以使pf指向某個文件的文件信息區(qū)(是一個結(jié)構(gòu)體變量)。通過該文件信息區(qū)中的信息就能夠訪問該文件。也就是說,通過文件指針變量可以找到與他關(guān)聯(lián)的相關(guān)文件。
總結(jié):每個被使用的文件都在內(nèi)存中開辟一個相應(yīng)的文件信息區(qū),用來存放文件的相關(guān)信息,這個相關(guān)信息是個結(jié)構(gòu)體,使用typedef類型重新定義,也就是FILE
。
文件的打開與關(guān)閉
在打開文件的同時,會返回一個FILE*
的指針變量指向該文件,也相當于建立了指針和文件的關(guān)系。
ANSIC規(guī)定使用fopen來打開文件,fclose來關(guān)閉文件。
相對路徑寫法(當前代碼所在路徑下)
… 表示上一級路徑
. 表示當前路徑
FILE* p = fopen("../test.txt","r"); //打開當前路徑低下 的test文件
絕對路徑寫法(明確指出)
fopen("C:\\2012_code\\84\\test\\test1.txt ","r");
打開方式
文件使用方式 | 含義 | 如果指定文件不存在 |
---|---|---|
“r”(只讀) | 為了輸入數(shù)據(jù),打開一個已存在的文本文件 | 出錯 |
“w”(只寫) | 為了輸出數(shù)據(jù),打開一個文本文件 | 建立一個新的文件(銷毀原來的文件信息) |
“a”(追加) | 向文本文件尾添加數(shù)據(jù) | 出錯 |
“rb”(只讀) | 為了輸入數(shù)據(jù),打開一個二進制文件 | 出錯 |
“wb”(只寫) | 為了輸出數(shù)據(jù),打開一個二進制文件 | 建立一個新的文件(銷毀原來的文件信息) |
“ab”(追加) | 向一個二進制文件添加數(shù)據(jù) | 出錯 |
“r+”(讀寫) | 為了讀和寫,打開一個文本文件 | 出錯 |
“w+”(讀寫) | 為了讀和寫,建立一個新的文件 | 建立一個新的文件 |
“a+”(讀寫) | 打開一個文件,在文件尾進行讀寫 | 建立一個新的文件 |
如果文件打開失敗,返回空指針NULL
FILE* pf = fopen("text.txt","r"); if(pf == NULL) { printf("%s\n",strerror(errno)); return 0; } fclose(pf); pf = NULL;
關(guān)閉文件時是值傳遞,不會改變文件本身。
文件的順序讀寫
結(jié)合MSDN食用更好
功能 | 函數(shù)名 | 適用于 |
---|---|---|
字符輸入函數(shù) | int fgetc( FILE * stream); | 所有輸入流 |
字符輸出函數(shù) | int fputc(int c, FILE* stream); | 所有輸出流 |
文本行輸入函數(shù) | char *fgets(char* string, int n, FILE* stream) | 所有輸入流 |
文本行輸出函數(shù) | int fputs(const char* string, FILE* stream) | 所有輸出流 |
格式化輸入函數(shù) | fscanf把文件假想成黑色的對話框。和普通的scanf相比,前面多了一個指向文件信息的指針。 | 所有輸入流 |
格式化輸出函數(shù) | fprintf 和普通的printf相比,前面多了一個指向文件信息的指針。(把數(shù)據(jù)放到文件里了) | 所有輸出流 |
二進制輸入 | fread : 返回類型是讀了幾個元素 | 文件 |
二進制輸出 | fwrite | 文件 |
鍵盤stdin和屏幕stdout都是外部設(shè)備, stdin和stdout都是FILE類型的
鍵盤stdin
和屏幕stdout
都是外部設(shè)備, stdin
和stdout
都是FILE類型的
鍵盤 - 標準輸入設(shè)備; 屏幕 - 標準輸出設(shè)備
是一個程序默認打開的兩個流設(shè)備。
關(guān)于fread的返回值
fread returns the number of full items actually read, which may be less than count if an error occurs or if the end of the file is encountered before reaching count. Use the feof or ferror function to distinguish a read error from an end-of-file condition. If size or count is 0, fread returns 0 and the buffer contents are unchanged.
對比一組函數(shù)
scanf
和printf
:針對標準輸入流、標準輸出流的格式化輸入、輸出語句
fscanf
和fprintf
:針對所有輸入流、所有輸出流的格式化輸入、輸出語句
sscanf
和sprintf
:
sscanf
:從字符串中讀取格式化的數(shù)據(jù)
Read formatted data from a string. int sscanf( const char *buffer, const char *format [, argument ] ... );
sprintf
:把格式化的數(shù)據(jù)存儲到字符串中
Write formatted data to a string. int sprintf( char *buffer, const char *format [, argument] ... );
用途:記錄日志
但是文件不安全,不夠高效 ------>>>> 數(shù)據(jù)庫 MySQL ?
使用文件的格式:
打開文件 — 安全檢查 ---- 操作 ---- 關(guān)閉文件
文件隨機讀取
fseek
根據(jù)文件指針的位置和偏移量定位文件指針。
fseek Moves the file pointer to a specified location. int fseek( FILE *stream, long offset, int origin ); offset: 偏移量(單位字節(jié)) origin:文件指針當前位置
文件當前位置的三種形式:
SEEK_CUR Current position of file pointer SEEK_END End of file SEEK_SET Beginning of file
ftell
返回文件指針相對于起始位置的偏移量。
ftell Gets the current position of a file pointer. long ftell( FILE *stream );
應(yīng)用
int main() { FILE* pf = fopen("test.txt","r"); if(pf == NULL) { printf("%s\n",strerror(errno)); } //1.定位文件指針 fseek(pf, 2, SEEK_CUR); //2.讀取文件 int ch = fgetc(pf); printf("%c",ch); fclose(pf); pf=NULL; return 0; }
rewind
:讓文件指針回到起始位置
rewind Repositions the file pointer to the beginning of a file. void rewind( FILE *stream );
文件結(jié)束判斷
在文件讀取過程中,不能用feof
函數(shù)的返回值直接用來判斷文件是否結(jié)束。
Return Value
The feof function returns a nonzero value after the first read operation that attempts to read past the end of the file. It returns 0 if the current position is not end of file. There is no error return.
而是應(yīng)用于當文件讀取結(jié)束的時候,判斷是讀取失敗結(jié)束,還是遇到文件尾結(jié)束。
1.文本文件讀取是否結(jié)束,判斷返回值是否為EOF
(fgetc
),或者NULL
(fgets
)
fgetc判斷是否是EOF
, fget
s判斷返回值是否為NULL
。
2.二進制文件的讀取結(jié)束判斷,判斷返回值是否小于實際要讀的個數(shù)。比如:通過fread
判斷返回值是否小于實際要讀的個數(shù)。
perror()
函數(shù)直接先打印你放在括號里面的字符串,然后接著打印冒號和錯誤信息。
ferror()
Return Value
If no error has occurred on stream, ferror returns 0. Otherwise, it returns a nonzero value.
應(yīng)用
int main() { FILE* pf = fopen("test.txt","r"); if(pf == NULL) { perror("open file test2.txt"); return 0; } //讀文件 int ch = 0; while((ch = fgetc(pf)) != EOF) { putc(ch); } if(ferror(pf)) { printf("error\n"); } else if(feof(of)) { printf("end of file"); } return 0; }
以上就是C語言文件操作方式超全詳解建議收藏的詳細內(nèi)容,更多關(guān)于C語言文件操作方式的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
C++深入刨析優(yōu)先級隊列priority_queue的使用
最近我學習了C++中的STL庫中的優(yōu)先級隊列(priority_queue)容器適配器,對于優(yōu)先級隊列,我們不僅要會使用常用的函數(shù)接口,我們還有明白這些接口在其底層是如何實現(xiàn)的2022-08-08