summaryrefslogtreecommitdiff
path: root/30_sort_lines/sortLines.c
blob: 3ef65ad1fa1e14d0f2442269a12f87f0f7b5bf7b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
#include <stdio.h>
#include <stdlib.h>
#include <string.h>


//This function is used to figure out the ordering
//of the strings in qsort.  You do not need
//to modify it.
int stringOrder(const void * vp1, const void * vp2) {
  const char * const * p1 = vp1;
  const char * const * p2 = vp2;
  return strcmp(*p1, *p2);
}
//This function will sort and print data (whose length is count).
void sortData(char ** data, size_t count) {
  qsort(data, count, sizeof(char *), stringOrder);
}

void processFile(FILE * f) {
  char ** lines = NULL;
  char * curr = NULL;
  size_t sz;
  size_t i = 0;

  //processing: building string array
  while (getline(&curr, &sz, f) >= 0) {
    lines = realloc(lines, (i+1) * sizeof(*lines));
    lines[i] = curr;
    curr = NULL;
    i++;
  }

  //sorting
  free(curr);
  sortData(lines, i);

  //printing then freeing each line
  for (size_t j = 0; j < i; j++) {
    printf("%s", lines[j]);
    free(lines[j]);
  }

  //clean up
  free(lines);
}

int main(int argc, char ** argv) {
  
  if (argc == 1) {
    // stdin
    processFile(stdin);
  }
  else {
    for (int i = 1; i < argc; i++) {
      // process each file one by one
        FILE *f = fopen(argv[i], "r");
        if (f == NULL) {
            fprintf(stderr, "Could not open file\n");
            return EXIT_FAILURE;
        }
        processFile(f);
        if (fclose(f) != 0) {
            fprintf(stderr, "Could not close file\n");
            return EXIT_FAILURE;
        }
    }
  }
  
  return EXIT_SUCCESS;
}