方法をサンプリングします。
エラー処理は省略。
ライブラリ sqort の sort 関数を使用しているので、独自に実装してください。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define LINE_MAX_SIZE 256
typedef struct filePos {
FILE *fp;
long pos;
} FilePos;
typedef struct myfile {
int lines;
int capacity;
FILE *fp;
FilePos *filePoss;
} MyFile;
MyFile *myfopen(const char *filepath){
char buff[LINE_MAX_SIZE];
MyFile *mfp;
mfp = (MyFile*)malloc(sizeof(MyFile));
mfp->lines = 0;
mfp->capacity=16;
mfp->filePoss=NULL;
mfp->filePoss=(FilePos*)realloc(mfp->filePoss, sizeof(FilePos)*(mfp->capacity *= 2));
mfp->fp = fopen(filepath, "r");
do{
mfp->filePoss[mfp->lines].fp = mfp->fp;
mfp->filePoss[mfp->lines].pos = ftell(mfp->fp);
if(++mfp->lines == mfp->capacity){
mfp->filePoss=(FilePos*)realloc(mfp->filePoss, sizeof(FilePos)*(mfp->capacity *= 2));
}
}while(NULL!=fgets(buff, LINE_MAX_SIZE, mfp->fp));
--mfp->lines;
return mfp;
}
void myfclose(MyFile *mfp){
free(mfp->filePoss);
fclose(mfp->fp);
free(mfp);
}
char *myfgets(FilePos *p, char *buff){
fseek(p->fp, p->pos, SEEK_SET);
return fgets(buff, LINE_MAX_SIZE, p->fp);
}
int myfcomp(const void *a, const void *b){
char buff_a[LINE_MAX_SIZE];
char buff_b[LINE_MAX_SIZE];
FilePos *fpa,*fpb;
fpa=(FilePos*)a;
fpb=(FilePos*)b;
myfgets(fpa, buff_a);
myfgets(fpb, buff_b);
return strcmp(buff_a, buff_b);
}
void myfsort(MyFile *mfp){
qsort(mfp->filePoss, mfp->lines, sizeof(FilePos), myfcomp);
}
void myfprint(MyFile *mfp){
char buff[LINE_MAX_SIZE];
int i;
for(i=0;i<mfp->lines ;++i)
printf("%s", myfgets(mfp->filePoss + i, buff));
}
void merge(const char *inpfile1, const char *inpfile2, const char *outfile){
FILE *fo;
MyFile *fi1, *fi2;
char buff_f1[LINE_MAX_SIZE];
char buff_f2[LINE_MAX_SIZE];
char buff_fo[LINE_MAX_SIZE];
char *outbuff=NULL;
int fi1_line, fi2_line;
int eof1, eof2;
fo=fopen(outfile, "w");
fi1=myfopen(inpfile1);
fi2=myfopen(inpfile2);
myfsort(fi1);
myfsort(fi2);
fi1_line=fi2_line=0;
eof1=eof2=0;
*buff_fo='\0';
while(1){
if(!eof1 && outbuff != buff_f2){
myfgets(&(fi1->filePoss[fi1_line]), buff_f1);
}
if(!eof2 && outbuff != buff_f1){
myfgets(&(fi2->filePoss[fi2_line]), buff_f2);
}
if(!eof1 && !eof2){
if(strcmp(buff_f1, buff_f2) <= 0){
outbuff=buff_f1;
++fi1_line;
} else {
outbuff=buff_f2;
++fi2_line;
}
} else if(!eof1 && eof2){
outbuff=buff_f1;
++fi1_line;
} else if(eof1 && !eof2){
outbuff=buff_f2;
++fi2_line;
} else {
break;
}
if(strcmp(outbuff, buff_fo) != 0){//duplicate check
strcpy(buff_fo, outbuff);
fputs(buff_fo, fo);
}
if(fi1->lines == fi1_line)
eof1 = !0;
if(fi2->lines == fi2_line)
eof2 = !0;
}
myfclose(fi2);
myfclose(fi1);
fclose(fo);
}
int main(){
merge("book1.txt", "book2.txt", "fixed.txt");
return 0;
}