lolamontes69

K+R Exercise5_15

Sep 25th, 2014
217
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 6.29 KB | None | 0 0
  1. /* Add the option -f to fold upper and lower case together, so that case
  2.  * distinctions are not made during sorting; for example, a and A compare equal.
  3.  *
  4.  * first add the -f flag
  5.  * use tolower() or to upper() for the caseless string compare
  6.  * */
  7.  
  8.  
  9. #include <stdio.h>
  10. #include <stdlib.h>
  11. #include <string.h>
  12.  
  13. #define MAXLINES 5000            /* max #lines to be sorted */
  14. #define MAXLEN 1000
  15. #define ALLOCSIZE 10000          /* size of available space */
  16.  
  17. static char allocbuf[ALLOCSIZE]; /* storage of alloc   */
  18. static char *allocp = allocbuf;  /* next free position */
  19.  
  20. char *lineptr[MAXLINES];         /* pointers to text lines */
  21.  
  22. char *alloc(int n);
  23. int readlines(char *lineptr[], int nlines);
  24. int getline(char *s, int lim);
  25. void writelines(char *lineptr[], int nlines);
  26. /* renamed because qsort() in stdlib.h */
  27. void qsort1(void *lineptr[], int left, int right,
  28.            int (*comp)(void *, void*));      /* a pointer to a function that returns
  29.                                                 an integer and two pointers as args. */
  30. int numcmp(char *, char *);
  31. /* renamed because strcmp() in stdlib.h */
  32. int strcmp1(char *s, char *t);
  33. void swap(void *v[], int, int);
  34.  
  35. static int numeric = 0;  /* 1 if numeric sort */
  36. static int reverse = 0;  /* 1 if reverse sort */
  37. static int fold = 0;
  38.  
  39.  
  40. /* sort input lines */
  41. main(int argc, char *argv[])
  42. {
  43.     int nlines;       /* number of input lines read */
  44.  
  45.     if(argc > 1 && strcmp1(argv[1], "-n") == 0)
  46.         numeric = 1;
  47.     else if(argc > 1 && strcmp1(argv[1], "-r") == 0)
  48.         reverse = 1;
  49.     else if(argc > 1 && strcmp1(argv[1], "-f") == 0)
  50.         fold = 1;
  51.     else if(argc > 1 && strcmp1(argv[1], "-d") == 0)
  52.         dirorder = 1;
  53.     if(argc > 2 && strcmp1(argv[2], "-n") == 0)
  54.         numeric = 1;
  55.     else if(argc > 2 && strcmp1(argv[2], "-r") == 0)
  56.         reverse = 1;
  57.     else if(argc > 2 && strcmp1(argv[2], "-f") == 0)
  58.         fold = 1;
  59.     else if(argc > 1 && strcmp1(argv[2], "-d") == 0)
  60.         dirorder = 1;
  61.     if(argc > 3 && strcmp1(argv[3], "-n") == 0)
  62.         numeric = 1;
  63.     else if(argc > 3 && strcmp1(argv[3], "-r") == 0)
  64.         reverse = 1;
  65.     else if(argc > 3 && strcmp1(argv[3], "-f") == 0)
  66.         fold = 1;
  67.     else if(argc > 1 && strcmp1(argv[3], "-d") == 0)
  68.         dirorder = 1;
  69.     if(argc > 4 && strcmp1(argv[4], "-n") == 0)
  70.         numeric = 1;
  71.     else if(argc > 4 && strcmp1(argv[4], "-r") == 0)
  72.         reverse = 1;
  73.     else if(argc > 4 && strcmp1(argv[4], "-f") == 0)
  74.         fold = 1;
  75.     else if(argc > 4 && strcmp1(argv[4], "-d") == 0)
  76.         dirorder = 1;
  77.  
  78.     if((nlines = readlines(lineptr, MAXLINES)) >= 0) {
  79.         qsort1((void**) lineptr, 0, nlines-1,
  80.           (int (*)(void *,void *))(numeric ? numcmp : strcmp1)); /* pointer to function that returns
  81.                                                                   an integer with two pointers as args */
  82.         writelines(lineptr,nlines);
  83.         return 0;
  84.     }
  85.     else {
  86.         printf("input too big to sort\n");
  87.         return 1;
  88.     }
  89. }
  90.  
  91. /* alloc: return pointer to n characters */
  92. char *alloc(int n)
  93. {
  94.     if(allocbuf + ALLOCSIZE - allocp >= n) {
  95.         allocp += n;
  96.         return allocp - n;
  97.     }
  98.     else return 0;
  99. }
  100.  
  101. /* readline: read input lines */
  102. int readlines(char *lineptr[], int maxlines)
  103. {
  104.     int len, nlines;
  105.     char *p, line[MAXLEN];
  106.  
  107.     nlines = 0;
  108.     while((len=getline(line, MAXLEN))>0)
  109.         if(nlines >= maxlines || (p = alloc(len+1)) == NULL)  /* len+1 to allocate next free */
  110.             return -1;                                        /* space after '\0' */
  111.         else {
  112.             line[len]='\0'; /* delete newline */
  113.             strcpy(p, line);
  114.             lineptr[nlines++] = p;
  115.         }
  116.     return nlines;
  117. }
  118.  
  119. /* getline: get a line of input into an array */
  120. int getline(char *s, int lim)
  121. {
  122.     int c, i;
  123.  
  124.     for(i=0; i<lim-1 && (c=getchar())!=EOF && c!='\n'; ++i)
  125.         s[i]=c;
  126.     s[i]='\0';
  127.     return i;
  128. }
  129.  
  130. /* writelines: write output lines */
  131. void writelines(char *lineptr[], int nlines)
  132. {
  133.     int i;
  134.     puts("---- Sorted words ----");
  135.     while(nlines-- > 0)
  136.         printf("%s\n", *lineptr++);
  137. }
  138.  
  139.  
  140. /* qsort: sort v[left]...v[right] into increasing order */
  141. void qsort1(void *v[], int left, int right,
  142.            int (*comp)(void *, void *))
  143. {
  144.     int i, last;
  145.     if(!reverse) {
  146.         if(left >= right)  /* do nothing if array contains */
  147.             return;        /* fewer than two elements */
  148.         swap(v, left, (left + right)/2);
  149.         last = left;
  150.         for(i=left+1; i<=right; i++)
  151.             if((*comp)(v[i], v[left])<0)    /* pointer to function and args */
  152.                 swap(v, ++last, i);
  153.         swap(v,left,last);
  154.         qsort1(v, left, last-1, comp);
  155.         qsort1(v, last+1, right, comp);
  156.     }
  157.     if(reverse) {
  158.         if(left >= right)  /* do nothing if array contains */
  159.             return;        /* fewer than two elements */
  160.         swap(v, left, (left + right)/2);
  161.         last = left;
  162.         for(i=left+1; i<=right; i++)
  163.             if((*comp)(v[i], v[left])>0)    /* pointer to function and args */
  164.                 swap(v, ++last, i);
  165.         swap(v,left,last);
  166.         qsort1(v, left, last-1, comp);
  167.         qsort1(v, last+1, right, comp);
  168.     }
  169. }
  170.  
  171. /* numcmp: compare s1 and s2 numerically */
  172. int numcmp(char *s1, char *s2)
  173. {
  174.     double v1, v2;
  175.  
  176.     v1 = atof(s1);
  177.     v2 = atof(s2);
  178.     if(v1<v2)
  179.         return -1;
  180.     else if(v1>v2)
  181.         return 1;
  182.     else
  183.         return 0;
  184. }
  185.  
  186. /* strcmp: return <0 if s<t, O if s==t, >0 if s>t */
  187. int strcmp1(char *s, char *t)
  188. {
  189.     int i;
  190.  
  191.     if(!fold) {
  192.         for(i=0; s[i] == t[i]; i++)    /* iterate until a difference found */
  193.             if(s[i]=='\0')             /* no differences found */
  194.                 return 0;
  195.         return s[i] - t[i];            /* Ascii arithmetic l-r==-6 */
  196.     }
  197.     else if(fold) {
  198.         for(i=0; tolower(s[i]) == tolower(t[i]); i++)    /* iterate until a difference found */
  199.             if(s[i]=='\0')             /* no differences found */
  200.                 return 0;
  201.         return tolower(s[i]) - tolower(t[i]);            /* Ascii arithmetic l-r==-6 */
  202.     }
  203. }
  204.  
  205. void swap(void *v[], int i, int j)
  206. {
  207.     void *temp;
  208.  
  209.     temp = v[i];
  210.     v[i] = v[j];
  211.     v[j] = temp;
  212. }
Advertisement
Add Comment
Please, Sign In to add comment