C程式中對流的訪問是通過檔案指標(file pointer)實現的。此指標的型別為FILE*
(FILE型別在<stdio.h>
中宣告),用檔案指標表示的特定流具有標準的名字,如果需要,還可以宣告另外一些檔案指標。
例如:FILE *fp1, *fp2
;
標準流和重定向
<stdio.h>
提供了3種標準流。可以直接使用,無需宣告
檔案指標 | 流 | 預設的含義 |
---|---|---|
stdin | 標準輸入 | 鍵盤 |
stdout | 標準輸出 | 螢幕 |
stderr | 標準錯誤 | 螢幕 |
許多作業系統可以通過一種稱為重定向(redirection)的機制來改變預設含義。
文字與二進位制檔案
<stdlib.h>
支援兩種二進位制型別的檔案:文字檔案(text file)
和二進位制檔案(binary file)。
文字檔案具有兩種二進位制檔案沒有的特性。
- 文字檔案分為若干行
- 文字檔案可以包含一個特殊的“檔案末尾”標記
用二進位制形式儲存數可以節省大量的空間
檔案操作
開啟檔案
FILE *fopen(const char * restrict filename, const char * restrict mode)
;
restrict
表明filename
和mode
所指向的字串的記憶體單元不共享。
注意:Windows程式設計師
會被看成是轉義字元
解決方法:
- 使用替代
- 使用/
fopen
函式返回一個指標
常見呼叫形式fp = fopen("in.dat", "r")
;fp
為FILE*
型別的變數
模式
文字檔案
字串 | 含義 |
---|---|
“r” | |
“w” | 開啟檔案用於寫(檔案不需要存在) |
“a” | 開啟檔案用於追加(檔案不需要存在) |
“r+” | 開啟檔案用於讀和寫,從檔案頭開始 |
“w+” | 開啟檔案用於讀和寫(如果檔案存在就截去) |
“a+” | 開啟檔案用於讀和寫(如果檔案存在就追加) |
開啟二進位制檔案+b
關閉檔案
int fclose(FILE *stream)
;
fclose函式必須是檔案指標,此指標來自fopen函式或freopen函式
如果成功關閉,會返回0;否則返回錯誤程式碼EOF(在<stdio.h>
中第一的巨集)
為開啟的流附加檔案
`FILE freopen( const char restrict filename,
const char *restrict mode,
FILE *restrict stream)`;
freopen
函式為已經開啟的流附加上一個不同的檔案。
最常見的做法是把檔案和一個標準流(stdin
, stdout
或stderr
)相關聯。
例如:為了使程式開始往檔案foo中寫資料,可以使用下列:
if (freopen("foo", "w", stdout) == NULL) {
...
}
從命令列獲取檔名
int main(int argc, char *argv[])
{
...
}
argc是命令列引數的數量,而argv是指指向引數字串的指標陣列。
argv[0]指向程式的名字,從argv[1]到argv[argc-1]都指向剩餘的實際引數
,而argv[argc]是空指標。
臨時檔案
FILE *tmpfile(void);
char *tmpnam(char *s);
檔案緩衝
int fflush(FILE *stream);
void setbuf(FILE *restrict stream, char * restrict buf);
int setvbuf(FILE * restrict stream,
char * restrict buf,
int mode,
size_t size);
緩衝(buffering)
把寫入流的資料儲存在記憶體的緩衝區中;當緩衝區滿了(或者關閉流)
時,對緩衝區進行“清洗”(寫入實際的輸出裝置)。
輸入流可以用類似的方法進行緩衝:緩衝區包含輸入裝置的資料,從
緩衝區讀取而不是此報告裝置本身讀取。
呼叫fflush()函式,程式可以按照我們所希望的頻率來清洗檔案
的緩衝區。
呼叫fflush(fp);
為和fp相關聯的檔案清洗緩衝區
呼叫fflush(NULL)
清洗全部輸出流。
如果呼叫成功,返回0,否則返回EOF
*subvbuf允許改變緩衝流的方法,並且允許控制緩衝區的大小和位置
其它檔案操作
int remove(const char *filename);
int rename(const char *old, const char *new);
使用檔名而不是檔案指標進行操作。
確保操作之前檔案關閉。