2013年3月4日 星期一

[C]多筆資料 二進制檔案 寫入-使用fwrite

前言

當我們在做C或C++語言的檔案讀寫時,時不時可能都會用到二進制的檔案讀取或寫入,而有時候我們可能會一次寫入多筆資料,如陣列,或是結構的陣列等,那麼這時候我們需要如何確保可以一次全部寫入,並一次全部讀取呢?

實作方式

此篇會先介紹寫入的部分,而若想知到讀取的部分,可以到此篇-C多筆資料的二進制檔案讀取-使用fread來了解。
首先,先讓我們來看看二進制的檔案寫入所提供的函式吧,參考C++ Reference,如下圖:
會發現是使用fwrite函式,而它的第一個參數是你所要儲存的變數資料的記憶體位置(也可以是陣列或結構),第二個參數是此變數的資料型態bytes大小,第三個參數是一次寫入的筆數(假若是5,就代表寫入5筆),最後是你所使用的FILE檔案指標。
所以,假若是單純一筆int的資料,可以這樣寫:
int n=5;
FILE *pf;
//開啟檔案....

fwrite(&n, sizeof(int), 1, pf); //寫入

//關閉...
而假若是多筆資料呢?
這才是我們這次的主要議題,解決的方式有兩種,第一種是最容易想到的-迴圈尋訪寫入,這邊我以結構陣列來述說如下:
roduct_t p_list[10];//宣告
int count=7; //假設7筆

for(i=0;i<count;i++){
      //寫入目前尋訪的資料,大小為結構的byte大小為,寫入一筆
fwrite(&p_list[i], sizeof(product_t), 1, pf); 
}
第二種就是先在檔案寫入時先寫入目前資料的筆數,之後,再一次寫入所有檔案資料,這樣讀取時就可以先知道筆數再依照筆數一次讀取!
roduct_t p_list[10];//宣告
int count=7; //假設7筆

//先寫入目前的筆數,確保讀檔可以先知道之前檔案的筆數
fwrite(&count,sizeof(int),1,pf); 

//參數一是陣列的記憶體位置,寫入的btyes大小為結構的大小,一次寫入count筆
fwrite(p_list,sizeof(product_t),count,pf); 

程式碼

  • 尋訪寫入
  • #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); 
    
  • 一次寫入
  • #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);
    
      

    沒有留言:

    張貼留言