From cb18bc8f3632a5f58abfe418d3885a2ba3ad068d Mon Sep 17 00:00:00 2001 From: sinanmohd Date: Wed, 29 Jun 2022 19:45:22 +0530 Subject: 5.16 --- 5.16.c | 204 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 204 insertions(+) create mode 100644 5.16.c diff --git a/5.16.c b/5.16.c new file mode 100644 index 0000000..39e8f96 --- /dev/null +++ b/5.16.c @@ -0,0 +1,204 @@ +#include +#include +#include +#include + +#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)(const char *, const char *)); +int numcmp(const char to[], const char from[]); +int strcmp_ignore_case(const char str1[], const char str2[]); +int reverse(const char str1[], const char str2[]); +int mystcmp(const char to[], const char from[]); +int (*compare)(const char str1[], const char str2[]); +int (*strcmp_base)(const char to[], const char from[]); +int isdirectory(char input); + +int directory_order_bool; + + +int +main(int argc, char *argv[]) +{ + char flag; + int numeric = 0, reverse_bool = 0, ignore_case_bool = 0; + int nlins; + + while (--argc > 0 && **++argv == '-') + while ((flag = *++*argv)) + switch (flag) { + case 'n' : + numeric = 1; + break; + case 'r' : + reverse_bool = 1; + break; + case 'f' : + ignore_case_bool = 1; + break; + case 'd' : + directory_order_bool = 1; + break; + default : + printf("Err: illigial option %c\n", flag); + } + + if (argc) + printf("Usage: sort -nrf\n"); + else if ((nlins = realines(lineptr, MAXLINES)) > 0) { + + strcmp_base = ignore_case_bool ? strcmp_ignore_case : mystcmp; + compare = numeric ? numcmp : strcmp_base; + + my_qsort(lineptr, 0, nlins - 1, 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)(const char *, const char *)) +{ + 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(const char str1[], const char str2[]) +{ + return (*compare)(str2, str1); +} + +int +strcmp_ignore_case(const char to[], const char from[]) +{ + if (directory_order_bool) { + for (; *to && *from; to++, from++) + if (isdirectory(tolower(*from)) && tolower(*from) != tolower(*to)) + break; + } + + else + for (; *to && *from && tolower(*to) == tolower(*from); to++, from++) + ; + + return tolower(*to) - tolower(*from); +} + +int +isdirectory(char input) +{ + if (isalpha(input) || isdigit(input) || isblank(input)) + return 1; + else + return 0; +} + +int +mystcmp(const char to[], const char from[]) +{ + if (directory_order_bool) { + for (; *to && *from; to++, from++) + if (isdirectory(*from) && *from != *to) + break; + } + + else + for (; *to && *from && *to == *from; to++, from++) + ; + + return *to - *from; +} + -- cgit v1.2.3