Skip to content

Commit 11652b4

Browse files
committed
added exercise 5-16
1 parent 3fa77b3 commit 11652b4

File tree

7 files changed

+263
-0
lines changed

7 files changed

+263
-0
lines changed

Chapter-5/Exercise 5-15/sort

0 Bytes
Binary file not shown.

Chapter-5/Exercise 5-16/alloc.c

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
#define ALLOCSIZE 10000 /* size of available space */
2+
3+
static char allocbuf[ALLOCSIZE]; /* storage for alloc */
4+
static char *allocp = allocbuf; /* next free position */
5+
6+
char *alloc(int n) /* return pointer to n characters */{
7+
/* end of the allocbuf - allocp should be >= n for it to fit */
8+
if (allocbuf + ALLOCSIZE - allocp >= n) { /* it fits */
9+
allocp += n;
10+
return allocp-n; /* old pointer */
11+
} else
12+
return 0;
13+
}
14+
15+
void afree(char *p) /* free storage pointed to by p */ {
16+
if (p >= allocbuf && p < allocbuf + ALLOCSIZE)
17+
allocp = p;
18+
}

Chapter-5/Exercise 5-16/alloc.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
#ifndef ALLOC_H
2+
#define ALLOC_H
3+
4+
char *alloc(int n);
5+
6+
void afree(char *p);
7+
8+
#endif

Chapter-5/Exercise 5-16/main.c

Lines changed: 170 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,170 @@
1+
#include <stdio.h>
2+
#include <string.h>
3+
#include <stdlib.h>
4+
#include <ctype.h>
5+
#include "my_io.h"
6+
#include "alloc.h"
7+
8+
#define MAXLINES 5000
9+
char *lineptr[MAXLINES];
10+
11+
void _qsort(void *lineptr[], int left, int right, int (*comp)(void *, void *), int order);
12+
13+
int numcmp(char *, char *);
14+
int strcmpi(char *, char *);
15+
int dircmp(char *, char *);
16+
int dircmpi(char *, char *);
17+
18+
int main(int argc, char **argv) {
19+
int numeric = 0;
20+
//int reverse = -1;
21+
int order = 1;
22+
int ignore_case = 0;
23+
int directory = 0;
24+
char *name = *argv;
25+
char c;
26+
27+
int (*compfun)(void *, void *) = strcmp;
28+
29+
/*if (argc > 1 && strcmp(*++argv, "-n") == 0)
30+
numeric = 1;*/
31+
while (--argc > 0 && **++argv == '-') {
32+
while (c = *++(*argv))
33+
switch(c) {
34+
case 'n':
35+
numeric = 1;
36+
break;
37+
case 'r':
38+
order *= -1;
39+
break;
40+
case 'f':
41+
ignore_case = 1;
42+
break;
43+
case 'd':
44+
directory = 1;
45+
break;
46+
default:
47+
printf("%s: illegal character %c\n", name, c);
48+
argc = -1;
49+
break;
50+
}
51+
}
52+
if (argc != 0) {
53+
printf("Usage: %s -n -r\n"
54+
"n: numeric sort\n"
55+
"r: reverse sort\n"
56+
"f: fold (ignore case) sort\n"
57+
"d: directory order sort\n", name);
58+
return 0;
59+
}
60+
61+
if (numeric)
62+
compfun = numcmp;
63+
else if (ignore_case) {
64+
compfun = directory ? dircmpi : strcmpi ;
65+
} else {
66+
compfun = directory ? dircmp : strcmp;
67+
}
68+
69+
//return 0;
70+
int nlines;
71+
if ((nlines = readlines(lineptr, MAXLINES)) >= 0) {
72+
_qsort((void **) lineptr, 0, nlines-1, compfun, order);
73+
writelines(lineptr, nlines);
74+
return 0;
75+
} else {
76+
printf("input too big to sort\n");
77+
return 1;
78+
}
79+
return 0;
80+
}
81+
82+
/* qsort: sort v[left]...v[right] into increasing order */
83+
void _qsort(void *v[], int left, int right, int (*comp)(void *, void *), int order) {
84+
int i, last;
85+
void swap(void *v[], int, int);
86+
87+
if (left >= right) return;
88+
swap(v, left, (left + right) / 2);
89+
last = left;
90+
for (i = left + 1 ; i <= right ; i++)
91+
if ((order)*(*comp)(v[i], v[left]) < 0)
92+
swap(v, ++last, i);
93+
swap(v, left, last);
94+
_qsort(v, left, last - 1, comp, order);
95+
_qsort(v, last + 1, right, comp, order);
96+
}
97+
98+
/* numcmp: compare s1 and s2 numerically */
99+
int numcmp(char *s1, char *s2) {
100+
double v1, v2;
101+
102+
v1 = atof(s1);
103+
v2 = atof(s2);
104+
if (v1 < v2)
105+
return -1;
106+
else if (v1 > v2)
107+
return 1;
108+
else
109+
return 0;
110+
}
111+
112+
/* dircmp: compare s1 and s2 in directory order
113+
* compare only letters, numbers and blanks */
114+
int dircmp(char *s1, char *s2) {
115+
char v1[1024], v2[1024];
116+
void strclean(char *s);
117+
118+
strcpy(v1, s1);
119+
strclean(v1);
120+
strcpy(v2, s2);
121+
strclean(v2);
122+
123+
return strcmp(v1, v2);
124+
}
125+
126+
/* dircmp, but with ignore case */
127+
int dircmpi(char *s1, char *s2) {
128+
char v1[1024], v2[1024];
129+
void strupr(char *);
130+
131+
strcpy(v1, s1);
132+
strupr(v1);
133+
strcpy(v2, s2);
134+
strupr(v2);
135+
return dircmp(v1, v2);
136+
}
137+
138+
void strclean(char *s) {
139+
while (*s != '\0') {
140+
if (!isalnum(*s) && *s != ' ')
141+
*s = '\\';
142+
s++;
143+
}
144+
}
145+
146+
/* strcmpi: compare s1 and s2 lexicographically, ignore case */
147+
int strcmpi(char *s1, char *s2) {
148+
void strupr(char *);
149+
150+
char v1[1024], v2[1024];
151+
strcpy(v1, s1);
152+
strupr(v1);
153+
strcpy(v2, s2);
154+
strupr(v2);
155+
156+
return strcmp(v1, v2);
157+
}
158+
159+
void strupr(char *s) {
160+
while(*s != '\0') {
161+
if (*s >= 'a' && *s <= 'z')
162+
*s = 'A' + (*s-'a');
163+
s++;
164+
}
165+
}
166+
167+
void swap(void *v[], int i, int j) {
168+
void *temp;
169+
temp = v[i], v[i] = v[j], v[j] = temp;
170+
}

Chapter-5/Exercise 5-16/my_io.c

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
#include <stdio.h>
2+
#include <string.h>
3+
#include "alloc.h"
4+
#define MAXLEN 1000 /* max length of any input line */
5+
6+
int _getline(char str[], int lim) {
7+
int c, i = 0;
8+
while (--lim && (c = getchar()) != EOF && c != '\n')
9+
str[i++] = c;
10+
if (c == '\n') str[i++] = c;
11+
str[i] = '\0';
12+
13+
return i;
14+
}
15+
16+
/* readlines: read input lines */
17+
int readlines(char *lineptr[], int maxlines) {
18+
int len, nlines;
19+
char *p, line[MAXLEN];
20+
21+
nlines = 0;
22+
while ((len = _getline(line, MAXLEN)) > 0)
23+
if (nlines >= maxlines || (p = alloc(len)) == NULL)
24+
return -1;
25+
else {
26+
line[len-1] = '\0'; /* delete newline */
27+
strcpy(p, line);
28+
lineptr[nlines++] = p;
29+
}
30+
return nlines;
31+
}
32+
33+
/* _readlines: doesn't use the alloc for memory allocation */
34+
int _readlines(char *lineptr[], int maxlines, char *linestore) {
35+
int len, nlines;
36+
char line[MAXLEN];
37+
while ((len = _getline(line, MAXLEN)) > 0) {
38+
if (nlines >= maxlines)
39+
return -1;
40+
else {
41+
line[len-1] = '\0'; /* delete the newline */
42+
strcpy(linestore, line);
43+
lineptr[nlines++] = linestore;
44+
}
45+
linestore += len;
46+
}
47+
return nlines;
48+
}
49+
50+
/* writelines: write output lines */
51+
void writelines(char *lineptr[], int nlines) {
52+
int i;
53+
54+
for (i = 0 ; i < nlines ; i++)
55+
printf("%s\n", lineptr[i]);
56+
}

Chapter-5/Exercise 5-16/my_io.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
#ifndef MY_IO_H
2+
#define MY_IO_H
3+
4+
int _getline(char str[], int limit);
5+
6+
int _readlines(char *lineptr[], int maxlines, char *linestore);
7+
int readlines(char *lineptr[], int maxlines);
8+
9+
void writelines(char *lineptr[], int nlines);
10+
11+
#endif

Chapter-5/Exercise 5-16/sort

13.2 KB
Binary file not shown.

0 commit comments

Comments
 (0)