檔案操作方法
fread和fwrite
檔案的操作分為兩種
1.把記憶體裡一組連續儲存區的內容複製到檔案裡(寫檔案)
2.把檔案裡一組連續儲存區的內容複製到記憶體裡(讀檔案)
fread函式可以採用二進位制的方式對檔案進行讀操作;fwrite函式可以採用二進位制的方式對檔案進行寫操作。
這兩個函式都需要四個引數:
1.記憶體裡第一個儲存區的地址
2.記憶體裡單個儲存區的大小
3.希望操作的儲存區個數
4.檔案指標
返回值表示實際操作的儲存區個數,
/*
*fwrite
* */
#include<stdio.h>
int main (){
int arr[] = {1,2,3,4,5},size = 0;
FILE *p_file = fopen("a.bin","wb");
if (p_file){
size = fwrite(arr,sizeof(int),5,p_file);
printf("size = %d\n",size);
fclose(p_file);
p_file = NULL;
}
return 0;
}
/*
*fread
* */
#include<stdio.h>
int main (){
int arr[5] = {0},size = 0,num = 0;
FILE *p_file = fopen("a.bin","rb");
if (p_file){
size = fread(arr,sizeof(int),10,p_file);
printf("size = %d\n",size);
for (num = 0;num <= 4;num++){
printf("%d ",arr[num]);
}
printf("\n");
fclose(p_file);
p_file = NULL;
}
return 0;
練習:編寫程式把以下二維陣列裡的所有數字記錄到二進位制檔案裡
11111
22222
33333
44444
55555
/*
*
*檔案操作練習
*
* */
#include<stdio.h>
int main (){
int size = 0,num = 0;
int arr[][5] = {1,1,1,1,1,2,2,2,2,2,3,3,3,3,3,4,4,4,4,4,5,5,5,5,5};
FILE *p_file = fopen("b.bin","wb");
if (p_file){
/*size = fwrite(arr,sizeof(int),25,p_file);
printf("size = %d\n",size);*/
for(num = 0;num <= 4;num++){
fwrite(arr[num],sizeof(int),5,p_file);
}
fclose(p_file);
p_file = NULL;
}
return 0;
}
編寫程式從上一個程式產生的檔案裡獲得所有數字並按照以下格式顯示在螢幕上
55555
44444
33333
22222
11111
/*
*
*
*檔案操作練習
*
* */
#include<stdio.h>
int main (){
int arr[5][5] = {0},num = 0;
int row = 0,col = 0;
FILE *p_file = fopen("b.bin","rb");
if (p_file){
for (num = 4;num >= 0;num--){
fread(arr[num],sizeof(int),5,p_file);
}
for (row = 0;row <= 4;row++){
for (col = 0;col <= 4;col++){
printf("%d ",arr[row][col]);
}
printf("\n");
}
fclose(p_file);
p_file = NULL;
}
return 0;
}
文字檔案操作
/*
*文字檔案演示
*
* */
#include<stdio.h>
#include<string.h>
int main (){
char buf[20] = {0};
int num = 0;
int arr[] = {1,22,333,4444,55555};
FILE *p_file = fopen("c.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函式可以按照規定的格式把數字記錄到文字檔案裡,fprintf函式的第一個引數是檔案指標,後面的引數就是printf函式的引數。
/*
*檔案練習
*
* */
#include<stdio.h>
int main (){
int num = 0;
int arr[] = {1,22,333,4444,55555};
FILE *p_file = fopen("d.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函式的第一個引數是檔案指標,後面的引數就是scanf函式的引數。
/*
*
*檔案操作練習
* */
#include<stdio.h>
int main (){
int num = 0,val = 0;
FILE *p_file = fopen("d.txt","r");
if (p_file){
for (num = 0;num <= 4;num++){
fscanf(p_file,"%d",&val);
printf("val = %d\n",val);
}
fclose(p_file);
p_file = NULL;
}
return 0;
}
這兩個函式不適合處理包含大量資料的檔案
練習:編寫程式從鍵盤得到多個考試成績並把他們記錄到文字檔案裡,考試成績的個數不確定。
/*
*檔案練習
*
* */
#include<stdio.h>
int main (){
int grade = 0;
FILE *p_file = fopen("e.txt","w");
if (p_file){
while (1){
printf("請輸入一個考試成績:");
scanf("%d",&grade);
if (grade < 0 || grade > 100){
break;
}
fprintf(p_file,"%d ",grade);
}
fprintf(p_file,"%d",-1);
fclose(p_file);
p_file = NULL;
}
return 0;
}
練習:編寫程式從上一個程式製作的檔案裡獲得所有考試成績並計算他們的和,把求和結果顯示在螢幕上。
/*
*
*文字檔案操作
* */
#include<stdio.h>
int main (){
int grade = 0,sum = 0;
FILE *p_file = fopen("e.txt","r");
if (p_file){
while (1){
fscanf(p_file,"%d ",&grade);
if (grade < 0 || grade > 100){
break;
}
sum += grade;
}
printf("sum = %d\n",sum);
fclose(p_file);
p_file = NULL;
}
return 0;
}
練習:編寫模擬人員資訊管理系統
每次執行程式的時候可以記錄使用者輸入的多個人員資訊,每個人員資訊包含整數型別ID,單精度浮點型別的工資以及姓名人員資訊要求記錄在二進位制檔案裡而且檔案內容可以擴充。
/*
*人員資訊管理系統
*
* */
#include<stdio.h>
#include<string.h>
typedef struct{
int id;
float salary;
char name[10];
}person;
int main (){
int choice = 0;
person prsn = {0};
FILE *p_file = fopen("person.bin","ab");
if (p_file){
while (1){
printf("請輸入人員ID:");
scanf("%d",&(prsn.id));
printf("請輸入工資:");
scanf("%g",&(prsn.salary));
scanf("%*[^\n]");
scanf("%*c");
printf("請輸入姓名:");
fgets(prsn.name,10,stdin);
if (strlen(prsn.name) == 9 && prsn.name[8] != '\n'){
scanf("%*[^\n]");
scanf("%*c");
}
fwrite(&prsn,sizeof(person),1,p_file);
printf("是否需要輸入下一個人員資訊?0表示不需要,1表示需要。");
scanf("%d",&choice);
if (!choice){
break;
}
}
fclose (p_file);
p_file =NULL;
}
return 0;
}
練習:將人員資訊顯示在螢幕上
/*
*
*人員資訊管理系統
*
* */
#include<stdio.h>
typedef struct {
int id;
float salary;
char name[10];
}person;
int main (){
int size = 0;
person prsn = {0};
FILE *p_file = fopen("person.bin","rb");
if (p_file){
while (1){
size = fread(&prsn,sizeof(person),1,p_file);
if (!size){
break;
}
printf("ID:%d\n",prsn.id);
printf("工資為:%g\n",prsn.salary);
printf("name:%s\n",prsn.name);
}
fclose(p_file);
p_file = NULL;
}
return 0;
}
檔案的位置指標
計算機裡為每個開啟的檔案保留一個整數,這個整數決定下一次讀寫操作的開始位置,這個位置一定在兩個相鄰位元組之間,這個整數就是檔案頭到這個位置之間包含的位元組個數,這個整數叫做檔案的位置指標,每當從檔案裡獲得n個位元組或向檔案裡寫入n個位元組後位置指標都會向後移動n個位元組。
/*
*
*位置指標演示
*
* */
#include<stdio.h>
int main (){
char ch = 0;
FILE *p_file = fopen("abc.txt","rb");
if (p_file){
fread(&ch,sizeof(char),1,p_file);
printf("ch = %c\n",ch);
fread(&ch,sizeof(char),1,p_file);
printf("ch = %c\n",ch);
fread(&ch,sizeof(char),1,p_file);
printf("ch = %c\n",ch);
fclose(p_file);
p_file = NULL;
}
return 0;
}
ftell
ftell函式可以獲得位置指標的數值
rewind
rewind函式可以把位置指標設定到檔案開頭
fseek
fseek函式可以把位置指標設定到檔案裡的任何位置,使用fseek函式的時候需要指定一個基準位置和目標位置到基準位置之間的距離。
SEEK_SET 0 把檔案頭作為基準位置
SEEK_CUR 1 把當前位置作為基準位置
SEEK_END 2 把檔案尾作為基準位置
如果目標位置在基準位置後邊則距離用非負數表示,如果目標位置在基準位置前邊則距離用負數表示。距離的絕對值就是兩個位元組之間包含的位元組個數。
/*
*
*位置指標演示
*
* */
#include<stdio.h>
int main (){
char ch = 0;
FILE *p_file = fopen("abc.txt","rb");
if (p_file){
printf("%ld\n",ftell(p_file));
fread(&ch,sizeof(char),1,p_file);
printf("ch = %c\n",ch);
//rewind(p_file);
fseek(p_file,2,SEEK_SET);
printf("%ld\n",ftell(p_file));
fread(&ch,sizeof(char),1,p_file);
printf("ch = %c\n",ch);
//rewind(p_file);
fseek(p_file,4,SEEK_CUR);
printf("%ld\n",ftell(p_file));
fread(&ch,sizeof(char),1,p_file);
printf("ch = %c\n",ch);
//rewind(p_file);
fseek(p_file,-3,SEEK_END);
fclose(p_file);
p_file = NULL;
}
return 0;
}
練習:編寫程式從person.bin檔案裡獲得所有人的id並把它們都顯示在螢幕上
/*
*人員資訊ID
*
* */
#include<stdio.h>
typedef struct {
int id;
float salary;
char name[10];
}person;
int main (){
int id = 0,size = 0;
FILE *p_file = fopen("person.bin","rb");
if (p_file){
while (1){
size = fread(&id,sizeof(int),1,p_file);
if (!size){
break;
}
printf("ID = %d\n",id);
fseek(p_file,sizeof(person) - sizeof(int),SEEK_CUR);
}
fclose(p_file);
p_file = NULL;
}
return 0;
}