[Exercise] Exercise 5-15. Add the option -f to fold upper and lower case together page 121

User avatar

Topic author
BJT
Site Admin
Site Admin
Posts: 141
Joined: Thu Apr 20, 2017 4:43 pm
Instruction: University Student
Gender:
Age: 27
Venezuela

Exercise 5-15. Add the option -f to fold upper and lower case together page 121

Post by BJT » Sun May 07, 2017 9:15 pm

Exercise 5-15. Add the option -f to fold upper and lower case together, so that case distinctions are not made during sorting; for example, a and A compare equal.

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <ctype.h>
  5.  
  6. #define MAXLINES 5000       /* max #lines to be sorted */
  7. char *lineptr[MAXLINES];    /* pointers to text lines */
  8.  
  9. int readlines(char *lineptr[], int nlines);
  10. void writelines(char *lineptr[], int nlines);
  11.  
  12. void my_qsort(void *lineptr[], int left, int right, int (*comp)(void *, void *), int reverse, int fold);
  13. int numcmp(char *, char *);
  14.  
  15. /* sort input lines */
  16. int main(int argc, char *argv[])
  17. {
  18.     int nlines;     /* number of input lines read */
  19.     int numeric = 0;/* if numeric sort */
  20.     int reverse = 0;/*reveser order*/
  21.     int fold = 0;   /*old upper lower case*/
  22.  
  23.     while (--argc>0&& **(++argv)=='-')
  24.     {
  25.         if( *(*(argv)+1)=='n')
  26.             numeric=1;
  27.         else if ( *(*(argv)+1)=='r')
  28.             reverse=1;
  29.         else if ( *(*(argv)+1)=='f')
  30.             fold=1;
  31.     }
  32.  
  33.     if ((nlines = readlines(lineptr, MAXLINES)) >= 0)
  34.     {
  35.         my_qsort((void**) lineptr, 0, nlines-1, (int (*)(void*,void*))(numeric ? numcmp : strcmp), reverse ? 1:0, fold ? 1:0);
  36.         writelines(lineptr, nlines);
  37.         return 0;
  38.     }
  39.     else
  40.     {
  41.         printf("input too big to sort\n");
  42.         return 1;
  43.     }
  44. }
  45.  
  46. #define MAXLEN 1000 /* max length of any input line */
  47. size_t get_line(char *, int);
  48. char *alloc(int);
  49.  
  50. /* readlines: read input lines */
  51. int readlines(char *lineptr[], int maxlines)
  52. {
  53.     int len, nlines;
  54.     char *p, line[MAXLEN];
  55.  
  56.     nlines = 0;
  57.     while ((len = get_line(line, MAXLEN)) > 0)
  58.         if (nlines >= maxlines || (p = alloc(len))== NULL)
  59.             return -1;
  60.         else
  61.         {
  62.             line[len-1] = '\0'; /* delete newline */
  63.             strcpy(p, line);
  64.             lineptr[nlines++] = p;
  65.         }
  66.  
  67.     return nlines;
  68. }
  69.  
  70. /* writelines: write output lines */
  71. void writelines(char *lineptr[], int nlines)
  72. {
  73.     int i;
  74.     for (i = 0; i < nlines; i++)
  75.         printf("%s\n", lineptr[i]);
  76. }
  77.  
  78. /* qsort: sort v[left]...v[right] into increasing order */
  79. void my_qsort(void *v[], int left, int right, int (*comp)(void *, void *), int reverse, int fold)
  80. {
  81.     int i, last;
  82.     void swap(void *v[], int, int);
  83.     if (left >= right)              /* do nothing if array contains */
  84.         return;                     /* fewer than two elements */
  85.     swap(v, left, (left + right)/2);
  86.     last = left;
  87.     for (i = left+1; i <= right; i++)
  88.         if(reverse)
  89.         {
  90.             if (fold)
  91.             {
  92.                 char a,b;
  93.  
  94.                 if (isalpha(*(char*)v[i]) && isalpha(*(char*)v[left]))
  95.                 {
  96.                     a=tolower(*(char*)v[i]);
  97.                     b=tolower(*(char*)v[left]);
  98.                     if ((*comp)(&a, &b) > 0)
  99.                         swap(v, ++last, i);
  100.                 }else if (isalpha(*(char*)v[i]))
  101.                 {
  102.                     a=tolower(*(char*)v[i]);
  103.                     if ((*comp)(&a, v[left]) > 0)
  104.                         swap(v, ++last, i);
  105.  
  106.                 }else if (isalpha(*(char*)v[left]))
  107.                 {
  108.                     b=tolower(*(char*)v[left]);
  109.                     if ((*comp)(v[i], &b) > 0)
  110.                         swap(v, ++last, i);
  111.                 }
  112.                 else
  113.                 {
  114.                     if ((*comp)(v[i], v[left]) > 0)
  115.                         swap(v, ++last, i);
  116.                 }
  117.             }
  118.             else
  119.             {
  120.                 if ((*comp)(v[i], v[left]) > 0)
  121.                     swap(v, ++last, i);
  122.             }
  123.         }
  124.         else
  125.         {
  126.             if (fold)
  127.             {
  128.                 char a,b;
  129.  
  130.                 if (isalpha(*(char*)v[i]) && isalpha(*(char*)v[left]))
  131.                 {
  132.                     a=tolower(*(char*)v[i]);
  133.                     b=tolower(*(char*)v[left]);
  134.                     if ((*comp)(&a, &b) < 0)
  135.                         swap(v, ++last, i);
  136.                 }else if (isalpha(*(char*)v[i]))
  137.                 {
  138.                     a=tolower(*(char*)v[i]);
  139.                     if ((*comp)(&a, v[left]) < 0)
  140.                         swap(v, ++last, i);
  141.  
  142.                 }else if (isalpha(*(char*)v[left]))
  143.                 {
  144.                     b=tolower(*(char*)v[left]);
  145.                     if ((*comp)(v[i], &b) < 0)
  146.                         swap(v, ++last, i);
  147.                 }
  148.                 else
  149.                 {
  150.                     if ((*comp)(v[i], v[left]) < 0)
  151.                         swap(v, ++last, i);
  152.                 }
  153.             }
  154.             else
  155.             {
  156.                 if ((*comp)(v[i], v[left]) < 0)
  157.                     swap(v, ++last, i);
  158.             }
  159.         }
  160.  
  161.     swap(v, left, last);
  162.     my_qsort(v, left, last-1, comp, reverse, fold);
  163.     my_qsort(v, last+1, right, comp, reverse, fold);
  164. }
  165.  
  166. /* numcmp: compare s1 and s2 numerically */
  167. int numcmp(char *s1, char *s2)
  168. {
  169.     double v1, v2;
  170.     v1 = atof(s1);
  171.     v2 = atof(s2);
  172.     if (v1 < v2)
  173.         return -1;
  174.     else if (v1 > v2)
  175.         return 1;
  176.     else
  177.         return 0;
  178. }
  179.  
  180. void swap(void *v[],int i, int j)
  181. {
  182.     void *temp;
  183.  
  184.     temp = v[i];
  185.     v[i] = v[j];
  186.     v[j] = temp;
  187. }
  188.  
  189. #define ALLOCSIZE 10000
  190. static char allocbuf[ALLOCSIZE];
  191. static char *allocp = allocbuf;
  192.  
  193. char *alloc(int n)
  194. {
  195.     if(ALLOCSIZE + allocbuf - allocp>= n )
  196.     {
  197.         allocp += n;
  198.         return allocp - n;
  199.     }
  200.     else
  201.         return 0;
  202. }
  203.  
  204. size_t get_line(char* f_line,int n)
  205. {
  206.     int c;
  207.     size_t size=(size_t)f_line;
  208.  
  209.     while(((size_t)f_line-size)<n && (c=getchar())!=EOF && c!='\n')
  210.         *f_line++=c;
  211.  
  212.     if(c=='\n')
  213.         *(f_line++)=c;
  214.  
  215.     *(f_line)='\0';
  216.  
  217.     return (size_t)f_line-size;
  218. }

input

Code: Select all

./c -n -f
Hello
hello again
12
4r3
23
765
My name 
my
21134
output

Code: Select all

my
My name 
Hello
hello again
4r3
12
23
765
21134
word count: 736

Link:
BBcode:
HTML:
Hide post links
Show post links

User avatar

Topic author
BJT
Site Admin
Site Admin
Posts: 141
Joined: Thu Apr 20, 2017 4:43 pm
Instruction: University Student
Gender:
Age: 27
Venezuela

Re: Exercise 5-15. Add the option -f to fold upper and lower case together page 121

Post by BJT » Thu May 11, 2017 1:53 am

Other version
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <ctype.h>
  5.  
  6. #define NUMERIC 1
  7. #define DECR 2
  8. #define FOLD 4
  9. #define MAXLINES 5000       /* max #lines to be sorted */
  10. char *lineptr[MAXLINES];    /* pointers to text lines */
  11.  
  12. int readlines(char *lineptr[], int nlines);
  13. void writelines(char *lineptr[], int nlines, int decr);
  14. void my_qsort(void *lineptr[], int left, int right, int (*comp)(void *, void *));
  15. int numcmp(char *, char *);
  16. int charcmp(char *, char *);
  17.  
  18. static char option=0;
  19.  
  20. /* sort input lines */
  21. int main(int argc, char *argv[])
  22. {
  23.     int nlines;     /* number of input lines read */
  24.  
  25.     while (--argc>0&& **(++argv)=='-')
  26.     {
  27.         if( *(*(argv)+1)=='n')
  28.         {
  29.             option|=NUMERIC;
  30.         }
  31.         else if ( *(*(argv)+1)=='r')
  32.         {
  33.             option|=DECR;
  34.         }
  35.         else if ( *(*(argv)+1)=='f')
  36.         {
  37.             option|=FOLD;
  38.         }
  39.     }
  40.  
  41.     if ((nlines = readlines(lineptr, MAXLINES)) >= 0)
  42.     {
  43.         if(option&NUMERIC)
  44.             my_qsort((void**) lineptr, 0, nlines-1,(int (*)(void*,void*))numcmp);
  45.         else if (option&FOLD)
  46.             my_qsort((void**) lineptr, 0, nlines-1,(int (*)(void*,void*))charcmp);
  47.         else
  48.             my_qsort((void**) lineptr, 0, nlines-1,(int (*)(void*,void*))strcmp);
  49.  
  50.         writelines(lineptr, nlines, option & DECR);
  51.         return 0;
  52.     }
  53.     else
  54.     {
  55.         printf("input too big to sort\n");
  56.         return 1;
  57.     }
  58. }
  59.  
  60. #define MAXLEN 1000 /* max length of any input line */
  61. size_t get_line(char *, int);
  62. char *alloc(int);
  63.  
  64. /* readlines: read input lines */
  65. int readlines(char *lineptr[], int maxlines)
  66. {
  67.     int len, nlines;
  68.     char *p, line[MAXLEN];
  69.  
  70.     nlines = 0;
  71.     while ((len = get_line(line, MAXLEN)) > 0)
  72.         if (nlines >= maxlines || (p = alloc(len))== NULL)
  73.             return -1;
  74.         else
  75.         {
  76.             line[len-1] = '\0'; /* delete newline */
  77.             strcpy(p, line);
  78.             lineptr[nlines++] = p;
  79.         }
  80.  
  81.     return nlines;
  82. }
  83.  
  84. /* writelines: write output lines */
  85. void writelines(char *lineptr[], int nlines, int decr)
  86. {
  87.     int i;
  88.  
  89.     if (decr) /*Print in reveser order*/
  90.         for(int i=nlines-1;i>=0;i--)
  91.             printf("%s\n", lineptr[i]);
  92.     else
  93.         for (i = 0; i < nlines; i++)
  94.             printf("%s\n", lineptr[i]);
  95. }
  96.  
  97. /* qsort: sort v[left]...v[right] into increasing order */
  98. void my_qsort(void *v[], int left, int right, int (*comp)(void *, void *))
  99. {
  100.     int i, last;
  101.     void swap(void *v[], int, int);
  102.     if (left >= right)              /* do nothing if array contains */
  103.         return;                     /* fewer than two elements */
  104.     swap(v, left, (left + right)/2);
  105.     last = left;
  106.     for (i = left+1; i <= right; i++)
  107.         if ((*comp)(v[i], v[left]) < 0)
  108.             swap(v, ++last, i);
  109.     swap(v, left, last);
  110.     my_qsort(v, left, last-1, comp);
  111.     my_qsort(v, last+1, right, comp);
  112. }
  113.  
  114. int charcmp(char *s, char *t)
  115. {
  116.     for(;tolower(*s)==tolower(*t);s++,t++)
  117.         if(*s=='\0')
  118.             return 0;
  119.     return tolower(*s)-tolower(*t);
  120. }
  121.  
  122. /* numcmp: compare s1 and s2 numerically */
  123. int numcmp(char *s1, char *s2)
  124. {
  125.     double v1, v2;
  126.     v1 = atof(s1);
  127.     v2 = atof(s2);
  128.     if (v1 < v2)
  129.         return -1;
  130.     else if (v1 > v2)
  131.         return 1;
  132.     else
  133.         return 0;
  134. }
  135.  
  136. void swap(void *v[],int i, int j)
  137. {
  138.     void *temp;
  139.  
  140.     temp = v[i];
  141.     v[i] = v[j];
  142.     v[j] = temp;
  143. }
  144.  
  145. #define ALLOCSIZE 10000
  146. static char allocbuf[ALLOCSIZE];
  147. static char *allocp = allocbuf;
  148.  
  149. char *alloc(int n)
  150. {
  151.     if(ALLOCSIZE + allocbuf - allocp>= n )
  152.     {
  153.         allocp += n;
  154.         return allocp - n;
  155.     }
  156.     else
  157.         return 0;
  158. }
  159.  
  160. size_t get_line(char* f_line,int n)
  161. {
  162.     int c;
  163.     size_t size=(size_t)f_line;
  164.  
  165.     while(((size_t)f_line-size)<n && (c=getchar())!=EOF && c!='\n')
  166.         *f_line++=c;
  167.  
  168.     if(c=='\n')
  169.         *(f_line++)=c;
  170.  
  171.     *(f_line)='\0';
  172.  
  173.     return (size_t)f_line-size;
  174. }
word count: 544

Link:
BBcode:
HTML:
Hide post links
Show post links

New Topic Post Reply Previous topicNext topic

Who is online

Users browsing this forum: No registered users and 1 guest