Daniela Favia
Daniela Favia

Reputation: 37

Quicksort on strings and file in C language

I have a question about the implementation of my Quicksort on strings in a file.

This exercise requires to input the file name of the file which you want to open and it can have at most 100 items. With the function char filling(FILE* myfile), every row contained in the file is copied into an array through a while cycle which ends at the End Of File.

Then it is called the function sort(strings, start, end, leq) to sort the array of strings which, at the end of the function, will be copied into a new file called sorted_myfile.

My question is: how can I test if my program works with files?

In the function char filling the declaration leq_fn leq refers to the declaration of a pointer to function typedef bool(* leq_fn )(char *, char *) which is included in the function of the quicksort. I hope I gave you all the information you need to help me. Thank you.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "quicksort.h"
#define MAX_LENGTH 100
#define EXTRA_LENGTH 101
#define LENGTH_STRING 255

char filling(FILE *myfile);
char *strings[MAX_LENGTH]; //Array of at most 100 items

char filling(FILE *myfile){
    char *row;
    char new_filename[LENGTH_STRING];
    FILE* sorted_myfile;
    int i=0, start=0, end=MAX_LENGTH-1;
    bool res_cmplen, res_cmpalpha, res_cmpalpha_nocase;
    FILE *sorted_myfile;

   while(i<=EOF){ 
     if(i==EXTRA_LENGTH){
        printf("The file has more than 100 items\n");
     }else{
        row = calloc(LENGTH_STRING, sizeof(char));
        fgets(row, LENGTH_STRING, myfile);
        strings[i]=row;
        i++;
        free(row);
    }
   }
   leq_fn leq;

   leq = cmp_len;
   res_cmplen = (*leq)("hello", "bye");
   leq = cmp_alpha;
   res_cmpalpha = (*leq)("HELLO", "bye");
   leq = cmp_alpha_nocase;
   res_cmpalpha_nocase = (*leq)("hello", "BYE");

   sort(strings, start, end, leq);
   scanf("%s", new_filename);
   sorted_myfile = fopen(new_filename, "w");
   for(i=0;i<end;i++){
     fputs(strings[i], sorted_myfile);
   }

   return 0;
}


int main(void) {
     char filename[LENGTH_STRING]; 
     FILE *myfile;

     printf("What is the file name?\n");
     scanf("%s", filename);
     myfile =  fopen(filename, "r");

     if(ferror(myfile)!=0){
       printf("The file doesn't exist\n");
     }else{
       filling(myfile);
    }

  return 0;
}

Upvotes: 0

Views: 570

Answers (1)

WedaPashi
WedaPashi

Reputation: 3872

I'd first start with fixing these:

  1. Change char *row; to char *row = NULL;
  2. Similarly change FILE* sorted_myfile; to FILE* sorted_myfile = NULL;
  3. Change bool res_cmplen, res_cmpalpha, res_cmpalpha_nocase; to
    bool res_cmplen = 0, res_cmpalpha = 0, res_cmpalpha_nocase = 0; or
    bool res_cmplen = 1, res_cmpalpha = 1, res_cmpalpha_nocase = 1;
    depending upon what is safer for implementation.
  4. Change FILE *sorted_myfile; to FILE *sorted_myfile = NULL;
  5. In main() change FILE *myfile; to FILE *myfile = NULL;
  6. After free(row); row becomes a dangling pointer and then you use it as is, and then on the last iteration of the loop, you leave it as is, which would invoke undefined behaviour. So, do a row = NULL; after freeing the memory.
  7. char *strings[MAX_LENGTH]; is not an //Array of at most 100 items, but an //array of MAX_LENGTH pointers. What happens here: strings[i]=row;?
  8. In the snippet below:

    while(i<=EOF){ 
       if(i==EXTRA_LENGTH){  
          printf("The file has more than 100 items\n");  
       }else{  
          row = calloc(LENGTH_STRING, sizeof(char));  
          fgets(row, LENGTH_STRING, myfile);  
          strings[i]=row;  
          i++;  
          free(row);  
       }
     }
    

    i is incremented in else{} condition and if(i==EXTRA_LENGTH) evaluates to true i.e. if i is equal to EXTRA_LENGTH, it will not be incremented or modified, since that takes place in else{} only. So When i == 255, your code will never enter else{} condition and only print "The file has more than 100 item " infinitely.

  9. This is a minor one, but, In main() I can see myfile = fopen(filename, "r");, this opens the file. Fine. Though I don't see when you close it, if you do at all. Missing a fclose(); somewhere may be?

Upvotes: 1

Related Questions