aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--5.14.c146
1 files changed, 146 insertions, 0 deletions
diff --git a/5.14.c b/5.14.c
new file mode 100644
index 0000000..9919fb6
--- /dev/null
+++ b/5.14.c
@@ -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);
+}