Untitled
unknown
plain_text
2 years ago
3.1 kB
7
Indexable
/* * CS107 Assignment 4 * Code by Brent Ju * * This program will take in either standard input or * a provided file and sort its contents and print them * in default sorted order (lexicographical). Two flags, * 'l' and 'n', are mutually exclusive, and these two flags * will sort the output either by string length or string * numberical value, respectively. The 'r' and 'u' flags will * print the result in reverser order and maintain only * unique values in the output, respectively. * */ #include <assert.h> #include <errno.h> #include <error.h> #include <getopt.h> #include <stdbool.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include "samples/prototypes.h" #define MAX_LINE_LEN 4096 #define MIN_NLINES 100 typedef int (*cmp_fn_t)(const void *p, const void *q); // compares 2 strings by lexicographical order, default int cmp_pstr(const void *p, const void *q) { return strcmp(*(char**)p, *(char**)q); } // compares strings by length int cmp_pstr_len(const void *p, const void *q) { return strlen(*(char**)p) - strlen(*(char**)q); } // compares strings by numeric value via atoi function int cmp_pstr_numeric(const void *p, const void *q) { int p_int = atoi(*(char**)p); int q_int = atoi(*(char**)q); return p_int - q_int; } /* * This function first reads input into a "max-sized" stack array * using fgets, and then the result will be copied to dynamically * allocated storage using strdup. If the '-u' flag is used to keep * only unique values, binsert will be used; otherwise, one call to * qsort will be made at the end to sort our array. * * Parameters uniq and reverse correspond to the flags passed in, and * cmp is a generic comparison function that differs based on input type. */ void sort_lines(FILE *fp, cmp_fn_t cmp, bool uniq, bool reverse) { char line[MAX_LINE_LEN]; int arr_size = MIN_NLINES; char** input_lines = malloc(arr_size * sizeof(char*)); assert(input_lines != NULL); // input_lines must be freed size_t num_lines = 0; char* fgets_result = NULL; while ((fgets_result = fgets(line, MAX_LINE_LEN, fp)) != NULL) { if (num_lines == arr_size) { input_lines = realloc(input_lines, 2 * arr_size * sizeof(char*)); assert(input_lines != NULL); arr_size *= 2; } char* allocated_str = strdup(line); // every index of input_lines must be freed assert(allocated_str != NULL); if (uniq) { binsert(&allocated_str, input_lines, &num_lines, sizeof(input_lines[0]), cmp); } else { input_lines[num_lines] = allocated_str; num_lines++; } } if (!uniq) { qsort(input_lines, num_lines, sizeof(input_lines[0]), cmp); } if (reverse) { for (int i = num_lines; i > 0; i--) { printf("%s\n", input_lines[i - 1]); free(input_lines[i - 1]); } } else { for (int i = 0; i < num_lines; i++) { printf("%s", input_lines[i]); free(input_lines[i]); } } free(input_lines); }
Editor is loading...