當我們在做C或C++語言的檔案讀寫時,時不時可能都會用到二進制的檔案讀取或寫入,而有時候我們可能會一次寫入多筆資料,如陣列,或是結構的陣列等,那麼這時候我們需要如何確保可以一次全部寫入,並一次全部讀取呢?
前言
當我們在做C或C++語言的檔案讀寫時,時不時可能都會用到二進制的檔案讀取或寫入,而有時候我們可能會一次寫入多筆資料,如陣列,或是結構的陣列等,那麼這時候我們需要如何確保可以一次全部寫入,並一次全部讀取呢?
使用fwrite
此篇會先介紹寫入的部分,而若想知到讀取的部分,可以到另一篇「C/C++多筆資料的二進制檔案讀取-使用fread」來了解。
首先,先讓我們來看看二進制的檔案寫入所提供的函式吧,參考C++ Reference,如下圖
節錄至:C++ Reference-fwrite
會發現是使用fwrite函式,而它的第一個參數是你所要儲存的變數資料的記憶體位置(也可以是陣列或結構),第二個參數是此變數的資料型態bytes大小,第三個參數是一次寫入的筆數(假若是3,就代表寫入3筆),最後是你所使用的FILE檔案指標。
所以,假若是單純一筆int的資料,可以這樣寫:
int n=5;
FILE *pf;
//開啟檔案....
//寫入n=5的資料,大小為int資料型態的byte,一次寫入一筆
fwrite(&n, sizeof(int), 1, pf); //寫入
//關閉...
而假若是多筆資料呢?
這才是我們這次的主要議題,解決的方式有兩種,第一種是最容易想到的-迴圈尋訪寫入,這邊我以結構陣列來述說如下:
尋訪寫入
product_t p_list[10];//宣告
int count=7; //假設7筆
for(i=0 ; i < count ; i++){
//寫入目前尋訪的資料,大小為結構的byte大小為,寫入一筆
fwrite(&p_list[i], sizeof(product_t), 1, pf);
}
第二種就是先在檔案寫入時先寫入目前資料的筆數,之後,再一次寫入所有檔案資料,這樣讀取時就可以先知道筆數再依照筆數一次讀取!
一次寫入
product_t p_list[10];//宣告
int count=7; //假設7筆
//先寫入目前的筆數,確保讀檔可以先知道之前檔案的筆數
fwrite(&count,sizeof(int),1,pf);
//參數一是陣列的記憶體位置,寫入的btyes大小為結構的大小,一次寫入count筆
fwrite(p_list,sizeof(product_t),count,pf);
程式碼
以下是兩種方式的全部程式碼範例:
1.尋訪寫入
#define MAX_SIZE 100
typedef struct{
int num;
char name[MAX_SIZE];
double price;
}product_t;
//main 宣告
product_t p_list[10];
int i,count;
char filename[MAX_SIZE];
FILE *pf;
////////////////////////////////////////
//寫入部分-尋訪方式
scanf("%s",filename);
pf = fopen(filename,"wb+");
if(!pf){
printf("open file error!\n");
return 0;
}
for(i=0 ; i < count ; i++){
//寫入目前尋訪的資料,大小為結構的byte大小為,寫入一筆
fwrite(&p_list[i], sizeof(product_t), 1, pf);
}
fclose(pf);
2.一次寫入
#define MAX_SIZE 100
typedef struct{
int num;
char name[MAX_SIZE];
double price;
}product_t;
//main 宣告
product_t p_list[10];
int i,count;
FILE *pf;
////////////////////////////////////////
//寫入部分-一次全部寫入
char filename[MAX_SIZE];
scanf("%s",filename);
pf = fopen(filename,"wb+");
if(!pf){
printf("open file error!\n");
return 0;
}
//先寫入目前的筆數,確保讀檔可以先知道之前檔案的筆數
fwrite(&count,sizeof(int),1,pf);
//參數一是陣列的記憶體位置,寫入的btyes大小為目前結構的大小,一次寫入count筆
fwrite(p_list,sizeof(product_t),count,pf);
fclose(pf);
文章中的敘述如有觀念不正確錯誤的部分,歡迎告知指正 謝謝 =)
另外要轉載請附上出處 感謝