diff options
-rw-r--r-- | 5.14.c | 146 |
1 files changed, 146 insertions, 0 deletions
@@ -0,0 +1,146 @@ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#define MAXLINES 5000 + +char *lineptr[MAXLINES]; + +int realines(char *lineptr[], int max); +void writelines(char *lineptr[], int nlins); +void my_qsort(char *lineptr[], int left, int right, int (*cmp)(void *, void *)); +int numcmp(const char to[], const char from[]); + +int reverse(char str1[], char str2[]); +int (*compare)(char str1[], char str2[]); + +int +main(int argc, char *argv[]) +{ + char flag; + int numeric = 0, reverse_bool = 0; + int nlins; + + while (--argc > 0 && **++argv == '-') + while ((flag = *++*argv)) + switch (flag) { + case 'n' : + numeric = 1; + break; + case 'r' : + reverse_bool = 1; + break; + default : + printf("Err: illigial option %c\n", flag); + } + + if (argc) + printf("Usage: sort -n\n"); + else if ((nlins = realines(lineptr, MAXLINES)) > 0) { + compare = numeric ? (int (*)(char *, char *))numcmp : (int (*)(char *, char *))strcmp; + my_qsort(lineptr, 0, nlins - 1, (int (*)(void *, void *)) (reverse_bool ? reverse : compare)); + writelines(lineptr, nlins); + } + + return 0; +} + +void swap(char *lineptr[], int to, int from); + +void +my_qsort(char *lineptr[], int left, int right, int (*cmp)(void *, void*)) +{ + int last, i; + + if (left >= right) + return; + + swap(lineptr, left, (left+right)/2); + last = left; + + for (i = left+1; i <= right; i++) { + if ((*cmp)(lineptr[i], lineptr[left]) < 0) + swap(lineptr, ++last, i); + + } + swap(lineptr, left, last); + + my_qsort(lineptr, left, last-1, cmp); + my_qsort(lineptr, last+1, right, cmp); +} + +int +numcmp(const char to[], const char from[]) +{ + double n1 = atof(to); + double n2 = atof(from); + + if (n1 < n2) + return -1; + else if (n1 > n2) + return 1; + else + return 0; +} + +void +swap(char *lineptr[], int to, int from) +{ + char *temp; + + temp = lineptr[to]; + lineptr[to] = lineptr[from]; + lineptr[from] = temp; +} + +void +writelines(char *lineptr[], int nlins) +{ + while (nlins--) + printf("%s", *lineptr++); +} + +#define MAXLEN 1000 +int sneed_getine(char str[], int max); + +int +realines(char *lineptr[], int max) +{ + int len, nlins; + char buff[MAXLEN], *temp; + + for (nlins = 0; (len = sneed_getine(buff, MAXLEN)) > 0; nlins++) { + if (nlins < max && (temp = malloc(len+1)) != NULL) { + strcpy(temp, buff); + lineptr[nlins] = temp; + } + + else + return -1; + } + + return nlins; +} + +int +sneed_getine(char str[], int max) +{ + char input; + char *str_og = str; + + while ( --max && (input = getchar()) != EOF && input != '\n') + *str++ = input; + + if (max && input == '\n') + *str++ = input; + + *str = '\0'; + + return str - str_og; +} + +int +reverse(char str1[], char str2[]) +{ + return (*compare)(str2, str1); +} |