csortingalphabetical-sort

Sorting a 2D string array in c


I am trying to sort this file that has this information below

  Easy,Category 3 hurricane,5-Sep,1950
  King,Category 4 hurricane,18-Oct,1950
  Florence,Category 1 hurricane,26-Sep,1953
  Hazel,Category 1 hurricane,9-Oct,1953
  Flossy,Category 1 hurricane,24-Sep,1956
  Donna,Category 4 hurricane,10-Sep,1960
  Cleo,Category 2 hurricane,27-Aug,1964
  Dora,Category 2 hurricane,10-Sep,1964
  Isbell,Category 2 hurricane,14-Oct,1964
  Betsy,Category 3 hurricane,8-Sep,1965
  Alma,Category 2 hurricane,9-Jun,1966
  Inez,Category 1 hurricane,8-Oct,1966
  Gladys,Category 2 hurricane,19-Oct,1968
  Agnes,Category 1 hurricane,19-Jun,1972
  Eloise,Category 3 hurricane,23-Sep,1975
  David,Category 2 hurricane,3-Sep,1979
  Elena,Category 3 hurricane,1-Sep,1985
  Kate,Category 2 hurricane,21-Nov,1985
  Floyd,Category 1 hurricane,12-Oct,1987
  Andrew,Category 5 hurricane,24-Aug,1992
  Erin,Category 2 hurricane,3-Aug,1995
  Opal,Category 3 hurricane,4-Oct,1995
  Earl,Category 1 hurricane,3-Sep,1998
  Georges,Category 2 hurricane,25-Sep,1998
  Irene,Category 1 hurricane,15-Oct,1999
  Charley,Category 4 hurricane,13-Aug,2004
  Frances,Category 2 hurricane,5-Sep,2004
  Ivan,Category 3 hurricane,16-Sep,2004
  Jeanne,Category 3 hurricane,26-Sep,2004
  Dennis,Category 3 hurricane,10-Jul,2005
  Katrina,Category 1 hurricane,25-Aug,2005
  Rita,Category 1 hurricane,20-Sep,2005
  Wilma,Category 3 hurricane,24-Oct,2005
  Hermine,Category 1 hurricane,2-Sep,2016
  Matthew,Category 2 hurricane,7-Oct,2016
  Irma,Category 4 hurricane,10-Sep,2017
  Michael,Category 5 hurricane,10-Oct,2018

i am using this code to do so.

#include <stdio.h>
  #include <string.h>
 
  #define NUM_LINES 37
  #define LINE_LENGTH 60
 
 
  void print(void);
  void select_sort_str(char list[][LINE_LENGTH], int n);
  int alpha_first(char list[][LINE_LENGTH], int min_sub, int max_sub);
 
 
  int main (void){
  //store each line in an array of strings
      FILE *inp;
      FILE *outp;
      char hurr[NUM_LINES][LINE_LENGTH];
 
      inp = fopen("hurricanes.csv","r");
      outp = fopen("out.txt","w");
      int num;
 
  //read in lines from file
      for (int i = 0; i<NUM_LINES; i++){
          fgets(hurr[i], LINE_LENGTH, inp);
      }
      inp = fopen("hurricanes.cvs","r");
 
      //printf("%s", hurr[0]);
  //define function
           
      select_sort_str(hurr, NUM_LINES);
 
 
  return(0);
  }
 
 
  int
  alpha_first(char list[][LINE_LENGTH],       // input - array of pointers to strings
              int min_sub,        // input - min and max subscripts of
              int max_sub)        //    portion of list to consider
  {
      int first, i;
 
      first = min_sub;
      for (i = min_sub + 1; i <= max_sub; ++i) {
          if (strcmp(list[i], list[first]) < 0) {
              first = i;
          }
      }
      return (first);
  }
 
  /*
   * Orders the pointers in an array list so they access strings in
   * alphabetical order
   * Pre: first n elements of list reference string of uniform case;
   *      n >= 0
   */
  void
  select_sort_str(char list[][LINE_LENGTH],   // input/output - array of pointers being
                                  // ordered to acces strings alphabetically
                  int n)          // input - number of elements to sort
  {
      int fill,           // index of element to contain next string in order
          index_of_min;   // index of next string in order
      char *temp;
 
  for (fill = 0; fill < n - 1; ++fill) {
          index_of_min = alpha_first(list, fill, n - 1);
 
          if (index_of_min != fill) {
              temp = list[index_of_min];
              list[index_of_min][LINE_LENGTH] = list[fill][LINE_LENGTH];
              list[fill][LINE_LENGTH] = *temp;
          }
      }
      for( int i =0; i<NUM_LINES; i++){
          printf("%s", list[i]);
      }
 
  }
 

but when I execute the code the output is not sorted properly. the output looks like this

Easy,Category 3 hurricane,5-Sep,1950
Aing,Category 4 hurricane,18-Oct,1950
Alorence,Category 1 hurricane,26-Sep,1953
Aazel,Category 1 hurricane,9-Oct,1953
Flossy,Category 1 hurricane,24-Sep,1956
Aonna,Category 4 hurricane,10-Sep,1960
Aleo,Category 2 hurricane,27-Aug,1964
Aora,Category 2 hurricane,10-Sep,1964
Asbell,Category 2 hurricane,14-Oct,1964
Aetsy,Category 3 hurricane,8-Sep,1965
Alma,Category 2 hurricane,9-Jun,1966
Anez,Category 1 hurricane,8-Oct,1966
Aladys,Category 2 hurricane,19-Oct,1968
Agnes,Category 1 hurricane,19-Jun,1972
Aloise,Category 3 hurricane,23-Sep,1975
David,Category 2 hurricane,3-Sep,1979
Alena,Category 3 hurricane,1-Sep,1985
Kate,Category 2 hurricane,21-Nov,1985
Aloyd,Category 1 hurricane,12-Oct,1987
Andrew,Category 5 hurricane,24-Aug,1992
Frin,Category 2 hurricane,3-Aug,1995
Cpal,Category 3 hurricane,4-Oct,1995
Carl,Category 1 hurricane,3-Sep,1998
Georges,Category 2 hurricane,25-Sep,1998
Crene,Category 1 hurricane,15-Oct,1999
Charley,Category 4 hurricane,13-Aug,2004
Crances,Category 2 hurricane,5-Sep,2004
Ivan,Category 3 hurricane,16-Sep,2004
Deanne,Category 3 hurricane,26-Sep,2004
Dennis,Category 3 hurricane,10-Jul,2005
Jatrina,Category 1 hurricane,25-Aug,2005
Hita,Category 1 hurricane,20-Sep,2005
Hilma,Category 3 hurricane,24-Oct,2005
Hermine,Category 1 hurricane,2-Sep,2016
Hatthew,Category 2 hurricane,7-Oct,2016
Hrma,Category 4 hurricane,10-Sep,2017
Michael,Category 5 hurricane,10-Oct,2018

I can tell that my code is sorting it in some fashion, but i am unable to fins the reason why it is not sorting alphabetically by the name. please let me know your thoughts.

Also there are no errors when compiling, only a few warnings about variables I have not used yet.


Solution

  • Below part is problematic in some ways:

              if (index_of_min != fill) {
                  temp = list[index_of_min];
                  list[index_of_min][LINE_LENGTH] = list[fill][LINE_LENGTH];
                  list[fill][LINE_LENGTH] = *temp;
              }
    

    First you are swapping a single character, not a series of characters(string). You have to declare another array of character and use that buffer to swap whole string with strncpy.

    Second you are accessing list[*][LINE_LENGTH] which is out of bounds. That causes undefined behaviour and in this case it writes in place of first element of next row(list[fill][LINE_LENGTH] => list[fill+1][0].

    Also, you have inp = fopen("hurricanes.cvs","r"); which, I think, should be csv. As Jonathan Leffler mentioned it is a good idea to keep strings that are used over the project as variables.