天天看點

C語言檔案分割與檔案合并(Dev C、VC等都可過編譯)

(本文章參考明日科技的《C語言項目案例分析》)

一、檔案分割

首先要實作,檔案的分割,很明顯就得知道檔案到底有多大,并将這個資料的n分之一作為每次檔案操作的标準;

int file_size(FILE *fp){
  int size = 0;
  while(!feof(fp)){
    fgetc(fp);
    size++;
  }
  rewind(fp);
  return size-1;
}      
這個函數實作了檔案大小的讀取,以位元組為機關,一定要注意的是在讀取完了之後,一定要使用rewind函數将指針重新置于檔案流頭,畢竟每次fgetc(fp)調用之後,檔案指針都會右移一個機關,若是不使用rewind,将會造成檔案分割失敗!!!

在fun_1(即檔案讀取函數當中),大多數都很好了解,除了下面這一串代碼

while(j<=num){
  rt:  printf("\n請輸入第%d個儲存的檔案名",j);
    scanf("%s",name);
    if((fp2=fopen(name,"wb"))==NULL){
      printf("\nError!!!Please enter again!!!");
      goto rt;  //錯誤即重新輸入,防止程式重新執行太麻煩!!!
    }
    while(d<=size*j/num){
      fputc(fgetc(fp1),fp2);
      d++;
    }
    j++;
    fclose(fp2);
  }      

其中num是想要分割的數量,外層while循環很好了解,用于保證分割數量;

内層while(d<=size*j/num),保證了每次輸出檔案僅僅隻輸出全部大小的num分之一

二、檔案組合

在了解了上面的分揀組合之後,檔案組合就顯得特别簡單,我認為稍微值得注意的隻有兩個

①​​

​while(fread(buffer,1,1,fp1)){ fwrite(buffer,1,1,fp2); size++; }​

保證了檔案一個一個位元組的輸出,其實問題也不大,對函數比較模糊的可以去菜鳥教程看看!!!
#include<stdio.h>
#include<stdlib.h>
#define

void startup();       //主菜單初始化界面 
void updateWithInput();  //與使用者輸入有關的更新
void fun_1();       //檔案分割 
void fun_2();       //檔案組合
int file_size(FILE *fp); //讀取檔案大小 


int main(){
  startup();
  updateWithInput();
} 

void startup(){
  //主菜單
  puts(" ");puts(" ");
  puts("     主菜單:");puts(" ");puts(" ");
  puts("             1> 檔案分割");
  puts("             2> 檔案組合");
  puts("             3> 退出程式");
  puts(" ");puts(" ");
}

void updateWithInput(){
  char input;
  while(!kbhit()){
    
    input = getch();
    if(input == '1')fun_1();
    if(input == '2')fun_2();
    if(input == '3')exit(-1);
  }
}

void fun_1(){
  int size;
  int ave_size;
  int num;
  int n;
  int j=1;
  int d=1;             //用于判斷每個位元組讀取情況 
  char name[25];
  FILE *fp1;
  FILE *fp2;
  system("cls");
  puts(" ");puts(" ");
  puts("     主菜單:");puts(" ");puts(" ");
  restart:printf("             請輸入讀取的檔案名:");
  scanf("%s",name);
  if((fp1=fopen(name,"rb"))==NULL){
    printf("Error!!! Please reenter!!!");
    goto restart;
  }
  size=file_size(fp1);
  printf("你想用将此檔案分割為幾部分?");
  scanf("%d",&num);
  ave_size = size / num;
  printf("\n此檔案大小為%d位元組,平均每個檔案大小為%d位元組\n",size,ave_size);
  while(j<=num){
  rt:  printf("\n請輸入第%d個儲存的檔案名",j);
    scanf("%s",name);
    if((fp2=fopen(name,"wb"))==NULL){
      printf("\nError!!!Please enter again!!!");
      goto rt;
    }
    while(d<=size*j/num){
      fputc(fgetc(fp1),fp2);
      d++;
    }
    j++;
    fclose(fp2);
  }
  fclose(fp1); 
  printf("\n\n\n\n\n                                                ");
  system("pause");
  system("cls");
  startup();
}

void fun_2(){
  system("cls");
  puts(" ");puts(" ");
  puts("     主菜單:");puts(" ");puts(" ");
  FILE *fp1;
  FILE *fp2;
  char name1[25];
  char name2[25];
  char buffer[SIZE];
  char condition;
  int size = 0;
  int j=1; 
  restart:printf("請輸入最終儲存的檔案名:");
  scanf("%s",name1);
  if((fp2=fopen(name1,"wb"))==NULL){
    printf("\nError!!!Please enter again");
    goto restart;
  }
  do{
    restart2:printf("\n請輸入用于儲存的檔案名%d:",j++);
    scanf("%s",name2);
    fflush(stdin);        //這個必須加不然回車會被接收到condition的getchar()中 
    if((fp1=fopen(name2,"rb"))==NULL){
      printf("\nError!!!Please enter again");
      j--;
      goto restart2;
    }
    while(fread(buffer,1,1,fp1)){
      fwrite(buffer,1,1,fp2);
      size++;
    }
    fclose(fp1);
    printf("是否繼續輸入?(輸入Y\\N 不區分大小寫):");   
    condition=getchar();
  }while(condition=='Y'||condition=='y');
  fclose(fp2); 
  printf("\n合并完成,檔案%s大小為%d位元組",name1,size);
  printf("\n\n\n\n\n                                                ");
  system("pause");
  system("cls");
  startup();
}

int file_size(FILE *fp){
  int size = 0;
  while(!feof(fp)){
    fgetc(fp);
    size++;
  }
  rewind(fp);
  return size-1;
}      

繼續閱讀