aboutsummaryrefslogblamecommitdiff
path: root/5.14.c
blob: 9919fb656a61b1fde40b1e1358711d3f61eb14fc (plain) (tree)

















































































































































                                                                                                 
#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);
}