0
votes

I am struggling with writing a C program that sorts numbers read from a number of files, in ascending order.

Requirements:

  1. create 3 files (file1, file2, file3)
  2. get numbers from the user and in file1
  3. find the smallest number (in file1) and copy it to file3
  4. copy the numbers from file1 to file2 except the smallest number that we copied to file3.
  5. copy the numbers in file2 to file1 (removing the all old numbers).
  6. using while function to repeat the steps above until we sort all numbers in ascending order in file3.
  7. copy numbers from file3 to file1 and print all the numbers on the screen (from file1).

Note: The program must be using only files to sort numbers and shouldn't use any array.

I am working on this for hours but now and sometimes it works and sometimes it does not. I don't really know what's wrong.

Any ideas or suggestions on solving this problem?

#include <conio.h>
#include <stdio.h>
// to save the position of the smallest number
int pos;

// to get numbers from the user and save them in file1
void getNumbers(FILE *file) {
  char x[255];
  printf("Enter numbers: ");
  scanf("%[^\n]s", &x);
  fprintf(file, "%s", x);
}

// to find the smallest number and copy it to file3
void findSmallestNo(FILE *file1, FILE *file3) {
  int x, temp;
  rewind(file1);
  fscanf(file1, "%d", &temp);
  pos = ftell(file1);
  while (!(feof(file1))) {
    fscanf(file1, "%d", &x);
    if (x < temp) {
      temp = x;
      pos = ftell(file1);
    }
  }
  fprintf(file3, "%d ", temp);
}

// to copy numbers from file1 to file2 except the smallest number that we copied
// in the file3

void copyToFile2(FILE *file1, FILE *file2) {
  int cur_pos, x;
  rewind(file1);
  rewind(file2);
  while (!(feof(file1))) {
    fscanf(file1, "%d", &x);
    cur_pos = ftell(file1);
    if (cur_pos != pos) {
      fprintf(file2, "%d ", x);
    }
  }
}

// to copy from file2 to file1 (it should delete the old data in file1)
void copyToFile1(FILE *file1, FILE *file2) {
  int x, count = 0;
  rewind(file2);

  while (!feof(file2)) {
    count++;
    fscanf(file2, "%d", &x);
    fprintf(file1, "%d ", x);
  }
}

// to print numbers on the screen
void print_file(FILE *file1) {
  int x;
  rewind(file1);
  printf("\nSorted Numbers: ");

  while ((fscanf(file1, "%d", &x)) == 1) {
    printf("%d ", x);
  }
  printf("\n");
}

int main() {
  int len, count = 1;
  FILE *pFile1, *pFile2, *pFile3;
  pFile1 = fopen("file1.txt", "w+");
  pFile2 = fopen("file2.txt", "w+");
  pFile3 = fopen("file3.txt", "a+");
  if (pFile1 == NULL) {
    printf("Couldn't open the file\n");
    exit(1);
  }
  // to get the count of numbers in file1
  getNumbers(pFile1);
  int getLength(FILE * file) {
    int nn, counting = 1;
    rewind(file);
    while ((fscanf(file, "%d ", &nn) == 1)) {
      counting++;
    }
    return counting;
  }
  len = getLength(pFile1);

  // while loop until var count is equal to the count of numbers in file1
  while (count < len) {
    ++count;
    findSmallestNo(pFile1, pFile3);
    copyToFile2(pFile1, pFile2);
    fclose(pFile1);
    pFile1 = fopen("file1.txt", "w+");
    copyToFile1(pFile1, pFile2);
  }

  fclose(pFile1);
  fclose(pFile3);
  pFile1 = fopen("file1.txt", "w+");
  pFile3 = fopen("file3.txt", "r");

  int number;
  // to copy numbers from file3 to file1
  while (count != 1) {
    fscanf(pFile3, "%d ", &number);
    fprintf(pFile1, "%d ", number);
    --count;
  }
  // to print numbers on the screen in file1
  print_file(pFile1);
  fclose(pFile1);
  fclose(pFile2);
  fclose(pFile3);

  return 0;
}
1
Side note: Your usage of while(!(feof(file1))){ looks wrong.MikeCAT
Can you tell us why you would only use files? Copying between files is rather inefficient!Bananenkönig
@Bananenkönig it's an assignment in the universiy and our professor wants us to use ony files.Anonymous Programmer
Do you know about linked list ? If you do, are you allowed to use them ?Dzious
What you would usually do with files is en.wikipedia.org/wiki/Merge_sortdratenik

1 Answers

0
votes
//#include <conio.h>
#include <stdio.h>
// to save the position of the smallest number

// to get numbers from the user and save them in file1
void getNumbers(char *filename) {
    char x[255];
    FILE *file;
    file = fopen(filename, "w");
    if (file == NULL) {
        printf("Couldn't open the file\n");
        return;
    }
    printf("Enter numbers: ");
    scanf("%[^\n]s", &x);
    fprintf(file, "%s", x);
    fclose(file);
}

// to find the smallest number and copy it to file3
int findSmallestNo(char *filename1, char *filename3) {
    int x, temp = 100000;
    FILE *file1, *file3;
    file1 = fopen(filename1, "r");
    file3 = fopen(filename3, "a");
    fscanf(file1, "%d", &temp);
    while (fscanf(file1, "%d", &x) == 1) {
        if (x < temp) {
            temp = x;
        }
    }
    fprintf(file3, "%d ", temp);
    fclose(file1);
    fclose(file3);
    return temp;
}

// to copy numbers from file1 to file2 except the smallest number that we copied
// in the file3

void copyToFile2(char *filename1, char *filename2, int min_value) {
    int flag = 0, x;
    FILE *file1, *file2;
    file1 = fopen(filename1, "r");
    file2 = fopen(filename2, "w");
    while (fscanf(file1, "%d", &x) == 1) {
        if (x != min_value || flag == 1) {
            fprintf(file2, "%d ", x);
        } else {
            flag = 1;
        }
    }
    fclose(file1);
    fclose(file2);
}

// to copy from file2 to file1 (it should delete the old data in file1)
void copyToFile(char *filename1, char *filename2) {
    int x;
    FILE *file1, *file2;
    file1 = fopen(filename1, "w");
    file2 = fopen(filename2, "r");
    rewind(file2);

    while (fscanf(file2, "%d", &x) == 1) {
        fprintf(file1, "%d ", x);
    }
    fclose(file1);
    fclose(file2);
}

// to print numbers on the screen
void print_file(char *filename) {
    int x;
    FILE *file;
    file = fopen(filename, "r");
    printf("\nSorted Numbers: ");

    while ((fscanf(file, "%d", &x)) == 1) {
        printf("%d ", x);
    }
    printf("\n");
    fclose(file);
}

int getLength(char *filename) {
    int nn, counting = 1;
    FILE *file;
    file = fopen(filename, "r");
    rewind(file);
    while ((fscanf(file, "%d ", &nn) == 1)) {
        counting++;
    }
    fclose(file);
    return counting;
}

void clearFile (char *filename) {
    FILE *file;
    file = fopen(filename, "w");
    fclose(file);
}

int main() {
    int len, count = 1;
    char *filename1 = "file1.txt";
    char *filename2 = "file2.txt";
    char *filename3 = "file3.txt";

    clearFile(filename3);

    // to get the count of numbers in file1
    getNumbers(filename1);

    len = getLength(filename1);

    // while loop until var count is equal to the count of numbers in file1
    while (count < len) {
        ++count;
        int cur_min = findSmallestNo(filename1, filename3);
        copyToFile2(filename1, filename2, cur_min);
        copyToFile(filename1, filename2);
    }

    int number;
    // to copy numbers from file3 to file1
    copyToFile(filename1, filename3);
    clearFile(filename3);
    // to print numbers on the screen in file1
    print_file(filename1);
    return 0;
}

i fixed your code, it seems working fine.

your algorithm works, but i think like @Bananenkönig said "Copying between files is rather inefficient!". The problem with your code is just about working with files.

Your way to read till end of file with fscanf will read 1 more time to find the eof, that's why you'll get some unwanted number in your results.