天天看点

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;
}      

继续阅读