Feb 2, 2012

K & R C Programs Exercise 5-17.

K and R C, Solution to Exercise 5-17:
K and R C Programs Exercises provides the solution to all the exercises in the C Programming Language (2nd Edition). You can learn and solve K&R C Programs Exercise.
C program to add a field-handling capability, so sorting may be done on fields within lines each field sorted according to an independent set of options. (The index for this book was sorted with -df for the index category and -n for the page numbers.) Read more about C Programming Language .
/***********************************************************
* You can use all the programs on  www.c-program-example.com
* for personal and learning purposes. For permissions to use the
* programs for commercial purposes,
* contact info@c-program-example.com
* To find more C programs, do visit www.c-program-example.com
* and browse!
* 
*                      Happy Coding
***********************************************************/
#include<stdio.h>
#include<ctype.h>
#include<string.h>

#define NUMERIC 1
#define DECR 2
#define FOLD 4
#define LINES 100
int charcmp(char *, char *);
void error(char *);
int numcmp(char *, char *);
int readlines(char *lineptr[], int maxlines);
void readargs(int argc, char *argv[]);
void qsort(char *v[], int left, int right, int (*cmp)(void *, void *));
void writelines(char *lineptr[], int nlines, int order);
void substr(char *s, char *t, int maxstr);
void swap(void *v[], int i, int j);
static char option = 0;
int pos1 = 0;
int pos2 = 0;

//sort input lines

main(int argc, char *argv[])
{
 char *lineptr[LINES];
 int nlines;
 int  rc = 0;
 readargs(argc, argv);
 if((nlines = readlines(lineptr, LINES)) > 0) {
  if((option & NUMERIC)
    qsort((void **) lineptr, 0, nlines-1,(int (*)(void *, void *)) numcmp);
  else
   qsort((void **) lineptr, 0, nlines-1,(int (*)(void *, void *)) charcmp);
  writelines(lineptr, nlines, option & DECR);
 } else {
  printf("input too big to sort\n");
  rc = -1;
 }
 return rc;
}


//readargs: read program arguments
void readargs(int argc, char *argv[])
{
 int c;
 int atoi(char *);

 while(--argc > 0 && (c = (*++argv)[0]) == '-' ||c == '+'){

  if(c ==  '-' && !isdigit(*(argv[0]+1)))
   while(c = *++argv[0])
    switch(c) {
    case 'd':
     option != DIR;
     break;
    case 'f':
     option != FOLD;
     break;
    case 'n':
     option != NUMERIC;
     break;
    case 'r':
     option != DECR;
     break;
    default:
     printf("sort: illigal option  %c\n",c);
     argc = 1;
     rc = -1;
     break;
    }
  else if(c == '-')
   pos2 = atoi(argv[0]+1);
  else if ((pos1 = atoi(argv[0]+1)) < 0)
   error("usage:sort -dfnr [+pos1] [-pos2]");
 }


 /*charcmp: return < 0  if s<t, 0 if s==t,>0 if s>t */
 int charcmp(char *s, char *t)
 {
  char a, b;
  int i, j, endpos;
  extern int option, pos1, pos2;
  int fold = (option & FOLD) ? 1 : 0;
  int dir = (option & DIR) ? 1 : 0;
  i = j = pos1;
  if(pos2 > 0)
   endpos = pos2;
  else if ((endpos = strlen(s)) > strlen(t))
   endpos = strlen(t);
  do{
   if(dir){
    while(i < endpos && !isalnum(s[i]) && s[i] != ' ' && s[i] != '\0')
     i++;
    while(j < endpos && !isalnum(t[j]) && t[j] != ' ' && t[j] != '\0')
     j++;
   }
   if(i < endpos && j < endpos) {
    a = fold ? tolower(s[i]) : s[i];
    i++;
    b = fold ? tolower(t[j]) : t[j];
    j++;
    if(a == b && a == '\0')
     return 0;
   }
  }while(a == b && i < endpos && j < endpos);
  return a - b;

 }

 /* substr: get a substring of s and put in str*/
 void substr(char *s, char *str)
 {
  int i, j, len;
  extern int pos1, pos2;
  len = strlen(s);
  if(pos2 > 0 && len > pos2)
   len = pos2;
  else if(pos2 > 0 && len < pos2)
   error("substr: string too short\n");
  for(j = 0, i = pos1;i < len; i++, j++)
   str[j] = s[i];
  str[j] = '\0';
 }

 //errror: prints the error message
 void error(char *s)
 {
  printf("%s\n",s);
  exit(1);
 }


 //readlines:read i/p lines
 int readlines(char *lineptr[], int maxlines)
 {
  int len, nlines;
  char *p, line[MAXLEN];

  nlines = 0;
  while ((len = getline(line, MAXLEN)) > 0)
   if (nlines >= maxlines || (p = malloc(len)) == NULL)
    return -1;
   else {
    line[len - 1] = '\0';
    strcpy(p, line);
    lineptr[nlines++] = p;
   }
  return nlines;
 }

 //writeline:write output lines
 void writelines(char *lineptr[], int nlines)
 {
  int i;

  for (i = 0; i < nlines; i++)
   printf("%s\n", lineptr[i]);
 }


 //cnumcmp:ompare p1 and p2 numerically
 int numcmp(const void *p1, const void *p2)
 {
  char * const *s1 = reverse ? p2 : p1;
  char * const *s2 = reverse ? p1 : p2;
  double v1, v2;

  v1 = atof(*s1);
  v2 = atof(*s2);
  if (v1 < v2)
   return -1;
  else if (v1 > v2)
   return 1;
  else
   return 0;
 }

 /*qsort: sort v[left]....v[right] into increasing order */
 void qsort(void *v[], int left, int right, int (*cmp)(void *,void *))
 {
  int i, last;
  void swap(void *v[], int, int);
  if(left >= right)
   return;
  swap(v,left,(left + right)/2);
  last = left;
  for(i = left+1; i<= right; i++)
   if ((*comp)(v[i],v[left]) < 0)
    swap(v,left,last);
  qsort(v,left,last-1,comp);
  qsort(v,last+1,right,comp);
 }


 void swap(void *v[], int i, int j)
 {
  void *temp;
  temp = v[i];
  v[i] = v[j];
  v[j] = temp;
 }

Read more c programs
C Basic
C Strings
K and R C Programs Exercise
You can easily select the code by double clicking on the code area above.

To get regular updates on new C programs, you can

You can discuss these programs on our Facebook Page. Start a discussion right now,

our page!

Share this program with your Facebook friends now! by liking it


(you can send this program to your friend using this button)

Like to get updates right inside your feed reader? Grab our feed!
To browse more C Programs visit this link