aboutsummaryrefslogblamecommitdiff
path: root/5.15.c
blob: 8fb9aedbc9bcc897c3de4c9e5236d8808b49367a (plain) (tree)



































































































































































                                                                                            
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.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)(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 (*compare)(const char str1[], const char str2[]);
int (*strcmp_base)(const char to[], const char from[]);


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;
        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 : strcmp;
    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[])
{
  for (; *to && *from && tolower(*to) == tolower(*from); to++, from++)
    ;

  return tolower(*to) - tolower(*from);
}