Low Level File I/O Compare Strings - c

I'm writing a program that takes a file with the 3 lines of encrypted passwords and compares them to all 4 lower case letters from aaaa - zzzz. The only issue I am having is that I can't figure out how to go line by line of the file I input and how to compare it to the 4 letter words individually. It should then print the 3 decrypted 4 letter words that correlate to the passwords from the file. Also if there are any types on how to improve my code, please let me know. I'm a beginner at this so I need clear explanations and examples if possible. Thank you.
EDIT*****
The main problem is in the all function and main. I'm not wanting to print the aaaa, aaab, aaac, etc to the screen but I want to put it in an char array so that i can compare each individually to each line from the file using crypt. So I need advice on how to put all 456976 combinations into an array, compare it to each line of code, and print the solutions to the screen.
file looks like this:
$1$6gMKIopE$I.zkP2EvrXHDmApzYoV.B.
$1$pkMKIcvE$WQfqzTNmcQr7fqsNq7K2p0
$1$0lMKIuvE$7mOnlu6RZ/cUFRBidK7PK.
My code looks like this:
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#define BUFFER_SIZE 1024
int my_fgets(char* buf, int len, int f)
{
for (int i = 0; i < len; i++,buf++)
{
int count = read(f, buf, 1);
if (!count || (buf[0] == '\n'))
{
buf[0] = 0;
return i;
}
}
return 0;
}
int inc(char *c,char begin, char end){
if(c[0]==0)
return 0;
if(c[0] == end){ // This make the algorithm to stop at char 'f'
c[0]=begin; // but you can put any other char
return inc(c+sizeof(char), begin, end);
}
c[0]++;
return 1;
}
char all(int a, int n,char begin, char end){
int i, j;
char *c = malloc((n+1)*sizeof(char));
char result[] = "";
for(i = a; i <= n; i++)
{
for(j=0;j<i;j++) c[j]=begin;
c[i]=0;
do {
int k = sizeof(result);
for (int g = 0; g < k -1; g++)
{
result[g] = c;
}
} while(inc(c,begin,end));
}
free(c);
}
int main(int argc, char* argv[])
{
char *result;
char let[456976];
int f = open("pass.txt", O_RDONLY);
if (f < 0)
return 0;
char buf[1024];
while (my_fgets(buf, sizeof(buf), f))
{
let = all(4,4,'a','z');
int i = 0;
result = crypt((let[i+1]), buf);
int ok = strcmp (result, pass) == 0;
return ok ? 0 : 1;
all(4, 4, 'a', 'z');
}
close(f);
}

I think you need to reword the question. Maybe the code below is what you want. Let's say you have a password, and you have a file which contains a list of encrypted passwords (or hash usually), you want to see if password is right or wrong. You compare the hash of the password with hashes in the file. I haven't tested this code.
ps, let me know if I am way off, I'll delete the answer.
void crypt(char* hash, const char* password_test) {
//create hash from password, or encrypt it or something?
}
int test_password(const char *filename, const char *password){
FILE *f;
f = fopen(filename, "r");
if (!f) return 0;
char password_hash[256];
crypt(password_hash, password);
char hash[256];
char buf[1024];
while (fgets(buf, sizeof(buf), f) != NULL)
{
crypt(hash, buf);
if (strcmp(password_hash, hash) == 0)
return 1;
}
fclose(f);
return 0;
}
void main() {
int result = test_password("test.txt", "password");
if (result == 1)
printf("password is good\n");
}
Reading line by line using open/read/close
int my_fgets(char* buf, int len, int f)
{
for (int i = 0; i < len; i++,buf++)
{
int count = read(f, buf, 1);
if (!count || (buf[0] == '\n'))
{
buf[0] = 0;
return i;
}
}
return 0;
}
int main(){
int f = open("test.txt", O_RDONLY);
if (f < 0) return 0;
char buf[1024];
while (my_fgets(buf, sizeof(buf), f))
printf("%s\n", buf);
close(f);
}

Related

How to shuffle 2 different text file into 1?

#include <stdio.h>
int main(){
char temp[64];
FILE *fp1=fopen("data/1.txt","a");
FILE *fp2=fopen("data/2.txt","r");
while(fgets(temp,64,fp2)!=NULL){
fputs(temp,fp1);
}
fclose(fp1);
fclose(fp2);
return 0;
}
With such code I was able to combine 2 different text file into 1.
data/1.txt contents: abcdefghijk
data/2.txt contents: ABCDE
Outcome: abcdefghijkABCDE
However, I am struggling with shuffling 2 different text file.
Wanted result: aAbBcCdDeEfghijk
Followings are my current code.
#include <stdio.h>
#include <string.h>
int main(){
FILE *fp1,*fp2,*fp_out;
char ch1,ch2;
int result=1;
fp1=fopen("data/1.txt","r");
fp2=fopen("data/2.txt","r");
fp_out=fopen("data/out.txt","w");
//shuffling code area//
fclose(fp1);
fclose(fp2);
fclose(fp_out);
char buf[64]={};
fp_out=fopen("data/out.txt","r");
fgets(buf,64,fp_out);
if(!strncmp("aAbBcCdDeEfghijk",buf,64))
printf("PASS\n");
else
printf("FAIL\n");
fclose(fp_out);
return 0;
}
How can I design a code in "shuffling code area" in order to have outcomes like wanted result? I have thought about making 2 different FOR loops and combining but it kept showed an error.
This is some dirty way to do the job.
You can read the file which ever you want to write first character first and then read a character from second file and write both into third file one after the other.
Just adding extra code as per your need.
This just works for your case , not tested with many cases and corner cases.
#include <stdio.h>
#include <string.h>
int main(){
FILE *fp1,*fp2,*fp_out;
char ch1,ch2;
int result=1;
int file1_content_over = 0;
int file2_content_over = 0;
fp1 = fopen("data/1.txt","r");
fp2 = fopen("data/2.txt","r");
fp_out=fopen("data/out.txt","w");
//shuffling code area//
// read till file1_content_over or file2_content_over is not finished
while(! file1_content_over || !file2_content_over)
{
ch1 = fgetc(fp1);
ch2 = fgetc(fp2);
if(ch1 != EOF)
fputc(ch1,fp_out);
else
file1_content_over = 1;
if(ch2 != EOF)
fputc(ch2,fp_out);
else
file2_content_over = 1;
}
//shuffling code area//
fclose(fp1);
fclose(fp2);
fclose(fp_out);
char buf[64]={};
fp_out=fopen("data/out.txt","r");
fgets(buf,64,fp_out);
printf("buf = %s\n", buf);
if(!strncmp("aAbBcCdDeEfghijk",buf,strlen("aAbBcCdDeEfghijk")))
printf("PASS\n");
else
printf("FAIL\n");
fclose(fp_out);
return 0;
}
Working for me! Not the best optimized code, I didnt get to much time to that!
Main():
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define MAX 100
int removingSPaces(char array[MAX], int sizeArray);
void orderChar(char bufFile1[MAX], char bufFile2[MAX], char bufOut[MAX], int maxSize, int sizeBuf1, int sizeBuf2);
int getChar(char buf[MAX], FILE *fp);
int main(){
FILE *fp1, *fp2, *fpOut;
char bufFile1[MAX] = {0}, bufFile2[MAX] = {0}, bufOut[MAX] = {0};
int sizeBuf1 = 0, sizeBuf2 = 0;
int maxSize=0;
if((fp1=fopen("file1.txt","r")) == NULL || (fp2=fopen("file2.txt","r")) == NULL || (fpOut=fopen("fileOut.txt","w")) == NULL){
perror("");
exit(1);
}
sizeBuf1 = getChar(bufFile1, fp1); //geting the chars from file1
fclose(fp1);
sizeBuf1 = removingSPaces(bufFile1, sizeBuf1); //removing the \n if exists from chars of file1
sizeBuf2 = getChar(bufFile2, fp2); //geting the chars from file2
fclose(fp2);
sizeBuf2 = removingSPaces(bufFile2, sizeBuf2); //removing the \n if exists from chars of file2
maxSize = sizeBuf1 + sizeBuf2; //Max Size to loop for
orderChar(bufFile1, bufFile2, bufOut, maxSize, sizeBuf1, sizeBuf2); //Order the chars!
fprintf(fpOut, "%s", bufOut); //Printing to the file
fclose(fpOut);
/* COPIED FROM YOUR CODE */
char buf[64]={0}; //Just added the 0, because you cant initialize the array like with only {}
if((fpOut=fopen("fileOut.txt", "r")) == NULL){
perror("");
exit(1);
}
fgets(buf,64, fpOut);
if(!strncmp("aAbBcCdDeEfghijk", buf, 64))
printf("PASS\n");
else
printf("FAIL\n");
fclose(fpOut);
/* COPIED FROM YOUR CODE */
return 0;
}
Functions():
int removingSPaces(char array[MAX], int sizeArray){
int size = sizeArray;
if(array[sizeArray -1] == '\n'){
array[sizeArray -1] = '\0';
size = strlen(array);
}
return size;
}
int getChar(char buf[MAX], FILE *fp){
char bufAux[MAX];
int size;
while(fgets(bufAux, sizeof(bufAux), fp)){
size = strlen(bufAux);
}
strcpy(buf, bufAux);
return size;
}
void orderChar(char bufFile1[MAX], char bufFile2[MAX], char bufOut[MAX], int maxSize, int sizeBuf1, int sizeBuf2){
int positionsF1=0, positionsF2=0;
int aux = 0; //This will starts organization by the first file! If you want to change it just change to 1;
for(int i=0; i < maxSize; i++){
if(aux == 0 && positionsF1 != sizeBuf1){
bufOut[i]=bufFile1[positionsF1];
if(positionsF2!=sizeBuf2){
aux = 1;
}
positionsF1++;
}else if(aux == 1 && positionsF2 != sizeBuf2){
bufOut[i]=bufFile2[positionsF2];
if(positionsF1!=sizeBuf1){
aux = 0;
}
positionsF2++;
}
}
}
Content of file 1:
abcdefghijk
Content of file 2:
ABCDE

How to save in a string the contents of a text file

This is the code why when I show in output the string I have all words but with in the final row a strange symbol , an ASCII random symbol...
My objective is to save in a string all words to operate with it.
For example I have this document:
Mario
Paul
Tyler
How can i save all words in a string??
#include <stdio.h>
#include <stdlib.h>
/* run this program using the console pauser or add your own getch, system("pause") or input loop */
int main(int argc, char *argv[]) {
int l,i=0,j=0,parole=0;
char A[10][10];
char leggiparola;
char testo[500];
FILE*fp;
fp=fopen("parole.txt","r");
if(fp!=NULL)
{
while(!feof(fp))
{
fscanf(fp,"%c",&leggiparola);
printf("%c", leggiparola);
testo[j]=leggiparola;
j++;
}
}
fclose(fp);
printf("%s",testo);
return 0;
}
Besides while(!feof(fp)) being "always wrong" you miss to 0-terminate the result string.
To do so place a
testo[j] = '\0'
just after the while-loop.
Instead of using fscanf, try with getc:
int leggiparola; /* This need to be an int to also be able to hold another
unique value for EOF besides 256 different char values. */
...
while ( (leggiparola = getc(fp)) != EOF)
{
printf("%c",leggiparola);
testo[j++] = leggiparola;
if (j==sizeof(testo)-1)
break;
}
testo[j] = 0;
Here's fslurp. I't a bit messy due to the need to grow the buffer manually.
/*
load a text file into memory
*/
char *fslurp(FILE *fp)
{
char *answer;
char *temp;
int buffsize = 1024;
int i = 0;
int ch;
answer = malloc(1024);
if(!answer)
return 0;
while( (ch = fgetc(fp)) != EOF )
{
if(i == buffsize-2)
{
if(buffsize > INT_MAX - 100 - buffsize/10)
{
free(answer);
return 0;
}
buffsize = buffsize + 100 * buffsize/10;
temp = realloc(answer, buffsize);
if(temp == 0)
{
free(answer);
return 0;
}
answer = temp;
}
answer[i++] = (char) ch;
}
answer[i++] = 0;
temp = realloc(answer, i);
if(temp)
return temp;
else
return answer;
}

Read from a text file and use each line to compare if they are anagrams

I must modify my program to accept input from
a file called anagrams.txt.This file should have two strings per line, separated by the # character. My program should read
each pair of strings and report back if each pair of strings is an anagram. For example consider the following content of anagrams.txt:
hello#elloh
man#nam
Astro#Oastrrasd
Your program should print out the following:
hello#elloh - Anagrams!
man#nam - Anagrams!
Astro#Oastrrasd- Not anagrams!
I should compile in g++
Here is the code to read from text:
int main()
{
char input[30];
if(access( "anagrams.txt", F_OK ) != -1) {
FILE *ptr_file;
char buf[1000];
ptr_file =fopen("anagrams.txt","r"); if (!ptr_file)
return 1;
while (fgets(buf,1000, ptr_file)!=NULL)
printf("%s",buf);
fclose(ptr_file);
printf("\n");
}
else{ //if file does not exist
printf("\nFile not found!\n");
}
return 0;
}
Code to find if the text are anagrams:
#include <stdio.h>
int find_anagram(char [], char []);
int main()
{
char array1[100], array2[100];
int flag;
printf("Enter the string\n");
gets(array1);
printf("Enter another string\n");
gets(array2);
flag = find_anagram(array1, array2);
if (flag == 1)
printf(" %s and %s are anagrams.\n", array1, array2);
else
printf("%s and %s are not anagrams.\n", array1, array2);
return 0;
}
int find_anagram(char array1[], char array2[])
{
int num1[26] = {0}, num2[26] = {0}, i = 0;
while (array1[i] != '\0')
{
num1[array1[i] - 'a']++;
i++;
}
i = 0;
while (array2[i] != '\0')
{
num2[array2[i] -'a']++;
i++;
}
for (i = 0; i < 26; i++)
{
if (num1[i] != num2[i])
return 0;
}
return 1;
}
You can try something like this:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#define MAXLINE 1000
#define MAXLETTER 256
int is_anagram(char *word1, char *word2);
void check_lines(FILE *filename);
int cmpfunc(const void *a, const void *b);
void convert_to_lowercase(char *word);
int
main(int argc, char const *argv[]) {
FILE *filename;
if ((filename = fopen("anagram.txt", "r")) == NULL) {
fprintf(stderr, "Error opening file\n");
exit(EXIT_FAILURE);
}
check_lines(filename);
fclose(filename);
return 0;
}
void
check_lines(FILE *filename) {
char line[MAXLINE];
char *word1, *word2, *copy1, *copy2;
while (fgets(line, MAXLINE, filename) != NULL) {
word1 = strtok(line, "#");
word2 = strtok(NULL, "\n");
copy1 = strdup(word1);
copy2 = strdup(word2);
convert_to_lowercase(copy1);
convert_to_lowercase(copy2);
if (is_anagram(copy1, copy2)) {
printf("%s#%s - Anagrams!\n", word1, word2);
} else {
printf("%s#%s - Not Anagrams!\n", word1, word2);
}
}
}
void
convert_to_lowercase(char *word) {
int i;
for (i = 0; word[i] != '\0'; i++) {
word[i] = tolower(word[i]);
}
}
int
is_anagram(char *word1, char *word2) {
qsort(word1, strlen(word1), sizeof(*word1), cmpfunc);
qsort(word2, strlen(word2), sizeof(*word2), cmpfunc);
if (strcmp(word1, word2) == 0) {
return 1;
}
return 0;
}
int
cmpfunc(const void *a, const void *b) {
if ((*(char*)a) < (*(char*)b)) {
return -1;
}
if ((*(char*)a) > (*(char*)b)) {
return +1;
}
return 0;
}
Since this looks like a University question, I won't provide a full solution, only a hint.
All you have to do is replace the stdin input part of the anagram-finding file with the code you wrote to read from a file: it's as simple as changing
printf("Enter the string\n");
gets(array1);
printf("Enter another string\n");
gets(array2);
to
// before program:
#define SIZE 1000
// inside main
if (access("anagrams.txt", F_OK) == -1){
printf("\nFile not found!\n");
return 1; // Abort the program early if we can't find the file
}
FILE *ptr_file;
char buf[1000];
ptr_file = fopen("anagrams.txt","r");
if (!ptr_file)
return 1;
char array1[SIZE], array2[SIZE];
while (fgets(buf, 1000, ptr_file)!=NULL){
// do all your anagram stuff here!
// there is currently one line of the input file stored in buf
// Hint: You need to split buf into array_1 and array_2 using '#' to separate it.
}
fclose(ptr_file);
printf("\n");
Additional comments:
Don't ever ever ever use gets. gets doesn't check that the string it writes to can hold the data, which will cause your program to crash if it gets input bigger than the array size. Use fgets(buf, BUF_SIZE, stdin) instead.
Beautiful code is good code. People are more likely to help if they can read your code easily. (fix your brackets)
Just for interest, a more efficient algorithm for checking anagrams is to use qsort to sort both arrays, then a simple string matcher to compare them. This will have cost O(mnlog(m+n)), as opposed to O(m^2 n^2), awith the current algorithm
You need to split every line you read by fgets (as you did) in to two strings, and pass them to your find_anagram function. You can do that using strtok:
int main()
{
int flag;
char buf[1000];
FILE *ptr_file;
//Check file existence
//Open the file for reading
while (fgets (buf, 1000, ptr_file) != NULL)
{
char *array1 = strtok(buf, "#");
char *array2 = strtok(NULL, "\n");
flag = find_anagram (array1, array2);
//Check flag value to print your message
}
return 0;
}
//put your find_anagram function
Don't forget to #include <string.h> to use strtok().

Adding words to a char *[] in C

I have a program that reads the words of two files (the first a wordlist, and the second an ebook from the Gutenberg project ) into two char *arrays.
I am trying to add all the unique words from the second char *array that don't appear in
the first char *array into a third char *array then print them.
This program adds the correct words, but is adding them more than once.
The error occurs in findOdds().
Note when I use a non-binary search method this program works correctly, but takes a long time.
What is the problem with my program? I apologize for my English.
#include <stdio.h>
#include <stdlib.h> /* for malloc() */
#include <ctype.h>
#include <string.h>
#define MAXCHAR 24
#define MAXLINES 150000
int add2array(FILE *fp, char *lineptr[]);
int findOdds(char *lineptr[], char *lineptr1[], int nlines, int nlines1);
int binsearch1(char *val, char *lineptr[], int nlines);
char *lineptr2[MAXLINES]; /* The unique words not in the word list */
int main(int argc, char *argv[])
{
FILE *my_stream, *my_stream1;
char *lineptr[MAXLINES], *lineptr1[MAXLINES];
int i, nlines, nlines1, nlines2;
/* Load the wordlist. */
my_stream = fopen("words.txt","r");
if(my_stream == NULL) {
printf("error: Couldn't open file\n");
return 2;
} else {
nlines = add2array(my_stream, lineptr);
fclose(my_stream);
}
if(nlines==-1) {
printf("error: Epic Failure to copy words to char *lineptr[]\n");
return -1;
}
/* Load the ebook. */
my_stream1 = fopen("horsemanship.txt","r");
if(my_stream1 == NULL) {
printf("error: Couldn't open file\n");
return 2;
} else {
nlines1 = add2array(my_stream1, lineptr1);
fclose(my_stream1);
}
if(nlines1==-1) {
printf("error: Epic Failure to copy words to char *lineptr[]\n");
return -1;
}
/* Find and print the unique words from the ebook not in the wordlist */
nlines2 = findOdds(lineptr, lineptr1, nlines, nlines1);
for(i=0; i<nlines2; i++)
printf("%s\n",lineptr2[i]);
return 0;
}
/* add2array: read the words from the file into char *lineptr[] */
int add2array(FILE *fp, char *lineptr[])
{
int nlines=0, c=0, pos=0;
char temp[MAXCHAR];
char *p;
while((c = getc(fp)) != EOF) {
if(isalpha(c))
temp[pos++] = tolower(c);
else if(!isalpha(c)) {
temp[pos] = '\0';
pos = 0;
if(isalpha(temp[0])){
if((p = malloc(sizeof(temp)))==NULL)
return -1;
strcpy(p, temp);
lineptr[nlines++] = p;
}
}
}
return nlines;
}
/* Add the unique words from lineptr1 not in lineptr to lineptr2 */
int findOdds(char *lineptr[], char *lineptr1[], int nlines, int nlines1)
{
char *p;
char temp[MAXCHAR];
int i, nlines2=0;
for(i=0; i<nlines1; i++) {
if(binsearch1(lineptr1[i], lineptr, nlines)==-1) {
if(binsearch1(lineptr1[i], lineptr2, nlines2)==-1) {
if((p = malloc(sizeof(temp)))==NULL)
return -1;
strcpy(p, lineptr1[i]);
lineptr2[nlines2++] = p;
}
}
}
return nlines2;
}
int binsearch1(char *val, char *lineptr[], int nlines)
{
int pos;
int start = 0;
int end = nlines-1;
int cond = 0;
while(start <= end){
pos=(start + end)/2;
if((cond = strcmp(lineptr[pos],val)) == 0)
return pos;
else if(cond < 0)
start = pos+1;
else
end = pos-1;
}
return -1;
}
Arrays must be sorted if you want to use binary search, as stated above by n.m.
in main() ...
shellsort1(lineptr1, nlines1);
/* Find and print the unique words from the ebook not in the wordlist */
nlines2 = findOdds(lineptr, lineptr1, nlines, nlines1);
...
int shellsort1(char *v[], int n)
{
int gap, i, j;
char temp[MAXCHAR];
char *p;
for(gap=n/2; gap>0; gap/=2)
for(i=gap; i<n; i++)
for(j=i-gap; j>=0 && strcmp(v[j],v[j+gap])>0; j-=gap) {
if((p = malloc(sizeof(temp)))==NULL)
return -1;
p = v[j];
v[j] = v[j+gap];
v[j+gap] = p;
}
return 0;
}

merging and sorting a text file in C

I am supoosed write a function that reads two text files line by line, compare them, delete the duplicates and but them into a third file in alphabetical order...I have been working on this for over a month and I am still stuck I have tried several ways to do this and come up with nothing...I was in formed that i have to use strcmp to do this and I cant use any other predefined sorting function...I have also looked around on this site and cannot find much that helps with this...any help would be greatly appreciated..Here is what I have so far:
#include<stdio.h>
#include<string.h>
main (void)
{
char str [200];
char str2 [200];
char new [100];
char temp [100];
int row = 10;
FILE *fa = fopen ("book1.dat", "r");
FILE *fb = fopen ("book2.dat", "r");
FILE *fc = fopen ("fixed.txt", "w");
int i;
int j;
int k;
while (fgets (str, 200, fa) !=NULL && fgets (str2, 200, fb) !=NULL)
{
puts(str);
puts(str2);
if (strcmp( str, str2) ==0 )
{
strcpy (str , new);
} else {
strcpy (new, str);
strcpy (new, str2);
}
}
for ( i = 0; i < row; i++)
{
for (j = i+1; j< row; j++)
{
if(strcmp(new[i], new [j]) > 0)
{
strcpy (temp, new);
strcpy(new, new);
strcpy(new, temp);
}
}
}
for (i = 0; i < length; i ++)
{
fputs(new, fc);
}
}
Your use of strcpy() is peculiar. Recall its signature:
char *strcpy(char *dest, const char *src)
Here's a usage that doesn't make immediate sense to me:
strcpy (new, str); // new now has str
strcpy (new, str2); // new now has str2
You've effectively overwritten something there. I would start from there, and see what else may not be working as you intend. Furthermore, if you can use gcc, look into using gdb as well to debug your code. (You would need to compile with the -g flag.)
First off, can you assume the duplicates from book1 and book2 line up nicely?
Think about how you would detect if the first entry in book1 is identical to the last entry in book2.
Secondly, you have to sort your output alphabetically. Sorting algorithms is kind of one of those common things that students are forced to do all the time. It builds character. For bonus kudos, implement quick sort.
sample a way.
error handling is omitted.
since we are using the sort function of the library sqort, implement your own.
#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;
}

Resources