### 文件操作
所有文件都是采用二進制方式記錄數字的。
如果文件里所有二進制數據都對應字符,則這種文件叫文本文件。
除了文本文件以外的文件,都叫做二進制文件。
C語言里提供兩種操作文件的方法,一種方法用來操作二進制文件(這種方法也可以操作文本文件),另外一種方法只能操作文本文件。
**二進制與文本文件的操作方式**
文件操作基本步驟,這種方式既可以操作二進制文件,也可以操作文本文件:
* 打開文件(fopen)
* 操作文件(fread/fwrite)
* 關閉文件(fclose)
fopen函數需要兩個參數:
* 要打開的文件路徑
* 打開文件的方式(決定了可以在程序中對文件做怎樣的操作)
打開方式如下選擇:
* r: 只能查看文件內容不能修改,只能從文件頭開始查看,如果文件不存在打開會失敗。
* r+: 比r多了修改功能,其他的都一樣。
* w: 只能修改文件內容不能查看,而且只能從文件頭開始修改,如果文件已經存在就刪除所有文件內容。
* w+: 比w多了查看功能。
* a: 只能修改不能查看,只能在文件末尾追加新內容,如果文件不存在就創建文件,如果文件已經存在則不會修改原有內容。
* a+: 比a多了查看功能。
* b: 它可以和前面六種中的任何一種混用,它表示程序要把文件當做二進制文件進行操作。
fopen函數的返回值應該記錄在文件指針里,程序中只能使用文件指針表示已經打開的文件。
fopen函數有可能打開失敗,如果失敗則返回值是NULL。
完成對文件的所有操作之后必須使用fclose函數關閉文件。
fclose函數需要文件指針作為參數。
fclose函數結束后文件指針成為野指針,因此必須恢復成空指針。
文件操作分為兩種:
* 把內存里一組連續的同類型存儲區內容拷貝到文件里,這個叫做寫文件。
* 把文件里一組連續的同類型存儲區內容拷貝到內存里,這個叫做讀文件。
fread函數可以對二進制文件進行讀操作。
fwrite函數可以對二進制文件進行寫操作。
這兩個函數都需要四個參數:
* 內存里第一個存儲區的地址。
* 內存里單個存儲區的大小
* 希望操作的存儲區個數
* 文件指針
它們的返回值表示實際操作的存儲區個數。
fwrite練習:
#include <stdio.h>
int main(){
int arr[] = {1, 2, 3, 4, 5};
int size = 0;
FILE *p_file = fopen("a.bin", "wb");
if (p_file){
size = fwrite(arr, sizeof(int), 5, p_file);
printf("寫入存儲器的個數是:%d\n", size);
fclose(p_file);
p_file = NULL;
}
return 0;
}
fread練習:
#include <stdio.h>
int main(){
int arr[5] = {0};
int size = 0;
int num = 0;
FILE *p_file = fopen("a.bin", "r");
if (p_file){
size = fread(arr, sizeof(int), 5, p_file);
printf("讀入存儲器的個數是:%d\n", size);
fclose(p_file);
p_file = NULL;
}
for (num = 0;num <= 4;num++){
printf("%d\n", *(arr + num));
}
return 0;
}
文本文件寫入練習:
使用fopen來實現文本文件的寫入的時候,需要先將數字轉換成字符類型,而且無法一起全部轉換,只能一個一個來進行轉換。
#include <stdio.h>
#include <string.h>
int main(){
int arr[] = {10, 20, 30, 40, 50};
int num = 0;
char buf[10] = {0};
FILE *p_file = fopen("a.txt", "wb");
if (p_file){
for (num = 0;num <= 4;num++){
sprintf(buf, "%d ", arr[num]);
fwrite(buf, sizeof(char), strlen(buf), p_file);
}
fclose(p_file);
p_file = NULL;
}
return 0;
}
**只能操作文本文件的標準函數**
fprintf函數可以把數據按照格式記錄到文本文件里。
fprintf函數的第一個參數是一個文件指針,后面的參數就是printf函數的參數。
#include <stdio.h>
int main(){
int arr[] = {10, 20, 30, 40, 50};
int num = 0;
FILE *p_file = fopen("a.txt", "w");
if (p_file){
for (num = 0;num <= 4;num++){
fprintf(p_file, "%d ", arr[num]);
}
fclose(p_file);
p_file = NULL;
}
return 0;
}
fscanf函數可以從文本文件中獲得數字并記錄到存儲區里。
fscanf函數的第一個參數是一個文件指針,后面的參數就是scanf函數的參數。
#include <stdio.h>
int main(){
int val = 0, num = 0;
FILE *p_file = fopen("a.txt", "r");
if (p_file){
for (num = 0;num <= 4;num++){
fscanf(p_file, "%d", &val);
printf("%d ", val);
}
printf("\n");
fclose(p_file);
p_file = NULL;
}
return 0;
}
### 位置指針
計算機里為每個打開的文件記錄了一個整數,這個整數表示下一次文件讀寫操作的開始位置。
這個位置一定在兩個相鄰的字節之間。
這個整數的數值就是文件頭到這個位置之間包含的字節個數, 這個整數叫做文件的位置指針。
每當向文件里寫入n個字節或者從文件里獲得n個字節,則位置指針的數值就會向后移動n個字節。
**ftell**
ftell函數可以用來獲得當前位置指針的數值。
#include <stdio.h>
int main(){
char ch = 0;
FILE *p_file = fopen("test.txt", "rb");
if (p_file){
fread(&ch, sizeof(char), 1, p_file);
printf("ch = %c\n", ch);
printf("位置指針的位置是: %ld\n", ftell(p_file));
fread(&ch, sizeof(char), 1, p_file);
printf("ch = %c\n", ch);
printf("位置指針的位置是: %ld\n", ftell(p_file));
fclose(p_file);
p_file = NULL;
}
}
**rewind**
rewind函數可以把位置指針挪動到文件開頭。
#include <stdio.h>
int main(){
char ch = 0;
FILE *p_file = fopen("test.txt", "rb");
if (p_file){
fread(&ch, sizeof(char), 1, p_file);
rewind(p_file);
printf("位置指針的位置是: %ld\n", ftell(p_file));
fread(&ch, sizeof(char), 1, p_file);
rewind(p_file);
printf("位置指針的位置是: %ld\n", ftell(p_file));
fclose(p_file);
p_file = NULL;
}
}
**fseek**
fseek函數可以把位置指針移動到文件中的任何位置。
fseek函數調用語句中需要指定一個基準位置以及目標位置到基準位置的距離。
* SEEK_SET 0 把文件頭作為基準位置。
* SEEK_CUR 1 把當前位置指針作為基準位置。
* SEEK_END 2 把文件尾作為基準位置。
如果目標位置在基準位置后則距離用整數表示。
如果目標位置在基準位置前則距離用負數表示。
距離的絕對值就是兩個位置之間包含的字節個數。
#include <stdio.h>
int main(){
char ch = 0;
FILE *p_file = fopen("test.txt", "rb");
if (p_file){
fseek(p_file, 2, SEEK_SET);
fread(&ch, sizeof(char), 1, p_file);
printf("ch = %c\n", ch);
printf("位置指針的位置是: %ld\n", ftell(p_file));
fseek(p_file, 2, SEEK_CUR);
fread(&ch, sizeof(char), 1, p_file);
printf("ch = %c\n", ch);
printf("位置指針的位置是: %ld\n", ftell(p_file));
fseek(p_file, -3, SEEK_END);
fread(&ch, sizeof(char), 1, p_file);
printf("ch = %c\n", ch);
printf("位置指針的位置是: %ld\n", ftell(p_file));
fclose(p_file);
p_file = NULL;
}
}