The C Programming Language (TCPL): Chapter 6

Exercise 6-4. Write a program that prints a distinct words in its input sorted into decreasing order of frequency of occurrence. Precede each word by its count.

#include
#include
#include

#define MAXWORDS 1024
#define MAXLENGTH 512

struct word {
char *name;
int count;
};

struct word wordlist[MAXWORDS];
int wordn = 0;

/* prototypes */
char *allocword(char *str);
int isword(char *str);
void addword(char *str);
int wordcmp(const void *a, const void *b);
void printwords();

int main()
{

char inputbuff[MAXLENGTH];
char tmpbuff[MAXLENGTH];
char *tmp;

while(fgets(inputbuff, MAXLENGTH, stdin) != NULL)
{

int i, k;
for(i = 0; inputbuff[i] != ''; i++)
{
if((inputbuff[i] == ' ' || inputbuff[i] == 't' || inputbuff[i] == 'n') && k != 0)
{
tmp = allocword(tmpbuff);
if(tmp == NULL)
{
printf("Error: Can't allocate enough space.n");
return 1;
}
strlcpy(tmp, tmpbuff, strlen(tmpbuff) + 1);
addword(tmp);
k = 0;
}
else
{
tmpbuff[k++] = inputbuff[i];
tmpbuff[k] = '';
}
}
}

printwords();
return 0;
}

char *allocword(char *str)
{
return (char *)malloc(sizeof(char) * (strlen(str) + 1));
}

int isword(char *str)
{
int i;
for(i = 0; i < wordn; i++) { if(!strncmp(wordlist[i].name, str, strlen(str))) { return i; } } return -1; } void addword(char *str) { int index; if((index = isword(str)) >= 0)
{
wordlist[index].count += 1;
} else {
wordlist[wordn].name = str;
wordlist[wordn].count = 1;
wordn++;
}

}

int wordcmp(const void *a, const void *b)
{
struct word *fst = (struct word *)a;
struct word *snd = (struct word *)b;

return -(fst->count - snd->count);
}

void printwords()
{
int i;

qsort(wordlist, wordn, sizeof(struct word), wordcmp);
for(i = 0; i < wordn; i++) { printf("%3i | %sn", wordlist[i].count, wordlist[i].name); } }

The C Programming Language (TCPL): Chapter 5

Exercise 5-10. Write a program expr, which evalutes a reverse Polish expression from the command line, where each operator or operand is a separate argument. For example, expr 2 3 4 + * evalutes 2 x (3 + 4).

#include
#include
#include

#define STACKSIZE 1024

double stack[STACKSIZE];
int stackn = 0;

double pop()
{
return stack[--stackn];
}

void push(double x)
{
stack[stackn++] = x;
}

int main(int argc, char *argv[])
{
int i;
double value = 0;

for(i = 1; i < argc; i++) { push(atof(argv[i])); float tmp; if(strlen(argv[i]) < 2) { if(argv[i][0] == '+') { pop(); /* removes operator */ push(pop() + pop()); } if(argv[i][0] == '-') { pop(); tmp = pop(); push(pop() - tmp); } if(argv[i][0] == '*') { pop(); push(pop() * pop()); } if(argv[i][0] == '/') { pop(); tmp = pop(); if (tmp != 0.0) { push(pop() / tmp); } else { printf("DIV BY 0n"); return 1; } } } } printf("%.2fn", pop()); return 0; }

The C Programming Language (TCPL): Chapter 4

Exercise 4-13. Write a recursive version of the function reverse(s), which reverses the string s in place.

#include
#include

void switchchar(char s[], int i, int j)
{
char tmp;

tmp = s[i];
s[i] = s[j];
s[j] = tmp;
}

void reverse(char s[])
{
static int i = 0;
static int len = 0;

if(i == 0)
{
len = strlen(s) - 1;
}

switchchar(s, i, (len - i));

i++;
if(i <= (len / 2)) { reverse(s); } } int main() { char str[] = "ABCDEF123456"; reverse(str); printf("%sn", str); return 0; }

The C Programming Language (TCPL): Chapter 3

Ex 3-3. Write a function expand(s1, s2) that expands shorthand notations like a-z in the string s1 into the equivalent complete list abc…xyz in s2. Allow for letters of either case and digits, and be prepared to handle cases like a-b-c and a-z0-9 and -a-z. Arrange that a leading – is taken literally.

#include
#include

void expand(char s1[], char s2[])
{

int i = 0;
char reverse = 0;

/* check if reverse */
if (s1[0] == '-')
{
reverse = 1;
i++;
}

int l = 0;
int end, start, ready;

start = 0;
end = 0;
ready = 0;
for(; s1[i] != ''; i++)
{
if(s1[i] != '-')
{
if (start == 0)
{
start = s1[i];
}
else
{
end = s1[i];
ready = 1;
}
}
else
{
/* for x-X-X */
if(ready == 0 && start == 0)
{
start = s1[i - 1];
l--;
}
}

if(ready == 1)
{
int k;
if(reverse == 0)
{
for(k = start; k <= end; k++, l++) { s2[l] = k; } } else { for(k = end; k >= start; k--, l++)
{
s2[l] = k;
}
}

start = 0; end = 0; ready = 0;
}

}

}

int main()
{
char s1[64], s2[256];

strncpy(s1, "a-b-ca-z0-9A-Z", 64);
strncpy(s2, "", 256);
expand(s1, s2);
printf("%s => %sn", s1, s2);

return 0;

}