Skip to content

Commit

Permalink
Exc. 6_01
Browse files Browse the repository at this point in the history
  • Loading branch information
rsm-lisper committed Jul 4, 2024
1 parent a3e21b0 commit 8e72dcc
Show file tree
Hide file tree
Showing 15 changed files with 350 additions and 0 deletions.
3 changes: 3 additions & 0 deletions chapter_6.structures/6_1.getword/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
BINARY=getword

include ../../Exercise_incl.mk
21 changes: 21 additions & 0 deletions chapter_6.structures/6_1.getword/binsearch.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# include <string.h>
# include "binsearch.h"

/* binsearch: find word in tab[0]...tab[n-1] */
int binsearch (char *word, struct key tab[], int n)
{
int cond;
int low, high, mid;
low = 0;
high = n - 1;
while (low <= high) {
mid = (low+high) / 2;
if ((cond = strcmp(word, tab[mid].word)) < 0)
high = mid - 1;
else if (cond > 0)
low = mid + 1;
else
return mid;
}
return -1;
}
12 changes: 12 additions & 0 deletions chapter_6.structures/6_1.getword/binsearch.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# ifndef BINSEARCH_H
# define BINSEARCH_H

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

/* binsearch: find word in tab[0]...tab[n-1] */
int binsearch (char *word, struct key tab[], int n);

# endif
25 changes: 25 additions & 0 deletions chapter_6.structures/6_1.getword/getch.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# include <stdio.h>

# define BUFSIZE 128

int buf[BUFSIZE]; /* buffer for ungetch */
int bufp = 0; /* next free position in buf */


/* getch: get a (possibly pushed-back) character */
int getch (void)
{
return (bufp > 0) ? buf[--bufp] : getchar();
}


/* ungetch: push character back on input */
void ungetch (int c)
{
if (bufp >= BUFSIZE) {
printf("ungetch: too many characters\n");
} else {
buf[bufp++] = c;
}
}

9 changes: 9 additions & 0 deletions chapter_6.structures/6_1.getword/getch.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# ifndef GETCH_H
# define GETCH_H

/* getch: get a (possibly pushed-back) character */
int getch (void);
/* ungetch: push character back on input */
void ungetch (int c);

# endif
106 changes: 106 additions & 0 deletions chapter_6.structures/6_1.getword/getword.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
# include <stdio.h>
# include <ctype.h>
# include "getch.h"

/*
Our version of getword does not properly handle underscores, string
constants, comments, or preprocessor control lines. Write a better version.
*/

int ignore_nonwords ()
{
int c = getch();

/* ignore white spaces */
if (isspace(c)) {
while (isspace(c = getch()))
;
ungetch(c);
return 1;
}

/* ignore character constants */
if (c == '\'') {
do {
if ((c = getch()) == '\\') {
getch();
c = getch();
}
} while (c != '\'' && c != EOF);
return 1;
}

/* ignore string constants */
if (c == '"') {
do {
if ((c = getch()) == '\\') {
getch();
c = getch();
}
} while (c != '"' && c != EOF);
return 1;
}

/* ignore preprocessor commands */
if (c == '#') {
while ((c = getch()) != EOF && c != '\n')
if ((c = getch()) == '\\') {
if ((c = getch()) == '\n')
c = getch();
else
ungetch(c);
}
return 1;
}

/* ignore comments */
if (c == '/') {
if ((c = getch()) == '*') {
while (c != EOF)
if ((c = getch()) == '*') {
if ((c = getch()) == '/')
break;
else
ungetch(c);
}
return 1;
}
else
ungetch(c);
}

/* ignore numbers */
if (isdigit(c)) {
while (isdigit(c = getch()) || c == '.')
;
ungetch(c);
return 1;
}

ungetch(c);
return 0;
}

/* getword: get next word or character from input */
int getword (char *word, int lim)
{
int c;
char *w = word;

while (ignore_nonwords())
;

if ((c = getch()) != EOF)
*w++ = c;
if (!isalpha(c) && c!='_') {
*w = '\0';
return c;
}
for ( ; --lim > 0; w++)
if (!isalnum(*w = getch()) && *w!='_') {
ungetch(*w);
break;
}
*w = '\0';
return word[0];
}
7 changes: 7 additions & 0 deletions chapter_6.structures/6_1.getword/getword.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# ifndef GETWORD_H
# define GETWORD_H

/* getword: get next word or character from input */
int getword (char *word, int lim);

# endif
59 changes: 59 additions & 0 deletions chapter_6.structures/6_1.getword/main.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
# include <stdio.h>
# include <ctype.h>
# include <string.h>
# include "getword.h"
# include "binsearch.h"

struct key keytab[] = {
{"auto", 0},
{"break", 0},
{"case", 0},
{"char", 0},
{"const", 0},
{"continue", 0},
{"default", 0},
{"do", 0},
{"double", 0},
{"else", 0},
{"enum", 0},
{"extern", 0},
{"float", 0},
{"for", 0},
{"goto", 0},
{"if", 0},
{"int", 0},
{"long", 0},
{"register", 0},
{"return", 0},
{"short", 0},
{"signed", 0},
{"sizeof", 0},
{"static", 0},
{"struct", 0},
{"switch", 0},
{"typedef", 0},
{"union", 0},
{"unsigned", 0},
{"void", 0},
{"volatile", 0},
{"while", 0}
};

# define NKEYS (int)(sizeof keytab / sizeof(struct key))
# define MAXWORD 128

/* count C keywords */
int main ()
{
int n;
char word[MAXWORD];
while (getword(word, MAXWORD) != EOF)
if (isalpha(word[0]))
if ((n = binsearch(word, keytab, NKEYS)) >= 0)
keytab[n].count++;
for (n = 0; n < NKEYS; n++)
if (keytab[n].count > 0)
printf("%4d %s\n",
keytab[n].count, keytab[n].word);
return 0;
}
9 changes: 9 additions & 0 deletions chapter_6.structures/6_1.getword/tests/0_getch.tin
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# ifndef GETCH_H
# define GETCH_H

/* getch: get a (possibly pushed-back) character */
int getch (void);
/* ungetch: push character back on input */
void ungetch (int c);

# endif
2 changes: 2 additions & 0 deletions chapter_6.structures/6_1.getword/tests/0_getch.tout
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
2 int
2 void
59 changes: 59 additions & 0 deletions chapter_6.structures/6_1.getword/tests/1_main.tin
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
# include <stdio.h>
# include <ctype.h>
# include <string.h>
# include "getword.h"
# include "binsearch.h"

struct key keytab[] = {
{"auto", 0},
{"break", 0},
{"case", 0},
{"char", 0},
{"const", 0},
{"continue", 0},
{"default", 0},
{"do", 0},
{"double", 0},
{"else", 0},
{"enum", 0},
{"extern", 0},
{"float", 0},
{"for", 0},
{"goto", 0},
{"if", 0},
{"int", 0},
{"long", 0},
{"register", 0},
{"return", 0},
{"short", 0},
{"signed", 0},
{"sizeof", 0},
{"static", 0},
{"struct", 0},
{"switch", 0},
{"typedef", 0},
{"union", 0},
{"unsigned", 0},
{"void", 0},
{"volatile", 0},
{"while", 0}
};

# define NKEYS (int)(sizeof keytab / sizeof(struct key))
# define MAXWORD 128

/* count C keywords */
int main ()
{
int n;
char word[MAXWORD];
while (getword(word, MAXWORD) != EOF)
if (isalpha(word[0]))
if ((n = binsearch(word, keytab, NKEYS)) >= 0)
keytab[n].count++;
for (n = 0; n < NKEYS; n++)
if (keytab[n].count > 0)
printf("%4d %s\n",
keytab[n].count, keytab[n].word);
return 0;
}
7 changes: 7 additions & 0 deletions chapter_6.structures/6_1.getword/tests/1_main.tout
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
1 char
1 for
3 if
2 int
1 return
1 struct
1 while
21 changes: 21 additions & 0 deletions chapter_6.structures/6_1.getword/tests/2_binsearch.tin
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# include <string.h>
# include "binsearch.h"

/* binsearch: find word in tab[0]...tab[n-1] */
int binsearch (char *word, struct key tab[], int n)
{
int cond;
int low, high, mid;
low = 0;
high = n - 1;
while (low <= high) {
mid = (low+high) / 2;
if ((cond = strcmp(word, tab[mid].word)) < 0)
high = mid - 1;
else if (cond > 0)
low = mid + 1;
else
return mid;
}
return -1;
}
7 changes: 7 additions & 0 deletions chapter_6.structures/6_1.getword/tests/2_binsearch.tout
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
1 char
2 else
2 if
4 int
2 return
1 struct
1 while
3 changes: 3 additions & 0 deletions chapter_6.structures/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
SUBDIRS=$(wildcard 6_*/)

include ../Chapter_incl.mk

0 comments on commit 8e72dcc

Please sign in to comment.