#include #define MAX 10000 void extern exit(int); typedef struct listnode {char *word; struct listnode *next;} List, *ListP; extern List *malloc(size_t); int strcomp(char *s, char *t) { for ( ; *s == *t++; s++ ) if (!*s) return 0; return (*s - *--t); } ListP construct(char *data, ListP n) { ListP new = malloc(sizeof(List)); new->word = data; new->next = n; return new; } char *head(ListP lp) { return lp->word; } ListP rest(ListP lp) { return lp->next; } int length(ListP lp) { return (lp == NULL) ? 0 : 1 + length(rest(lp)); } isMember(char *w, ListP lp) { if (lp == NULL) return 0; if (strcomp(w, lp->word)==0) return 1; return isMember(w, rest(lp)); } ListP addLast(char *w, ListP lp) { return (lp == NULL) ? construct(w, lp) : construct (head(lp), addLast(w, rest(lp))); } /* For reading words from a file and storing them in wordsbuffer we need */ FILE *inFile; char wordsbuffer[MAX]; char *previousword = wordsbuffer - 1; // doesn't exist yet char *thisword = wordsbuffer - 1; // doesn't exist yet char *nextword = wordsbuffer; // next word will go here int done = 0; int alpha(char ch) { return ((ch>='a'&&ch<='z')||(ch>='A'&&ch<='Z')); } char lower(char c) { return (c >= 'A' && c <= 'Z') ? c + 'a' - 'A' : c; } char *getword() { if (done) return (char*) EOF; previousword = thisword; thisword = nextword; while (!alpha(*nextword = fgetc(inFile)) && (*nextword != EOF)); if (*nextword == EOF) return (char*) EOF; *nextword = lower(*nextword); while (alpha(*++nextword = lower(fgetc(inFile)))); if (*nextword == EOF) done = 1; *nextword++ = '\0'; return thisword; } void ungetword() { // ungets at most one word if (previousword < wordsbuffer) printf("Attempt to unget what has not been got\n"); else { nextword = thisword; thisword = previousword; previousword = wordsbuffer - 1; } } ListP reverse (ListP l) { /* You need to write this properly */ return l; } main(int argc, char *argv[]) { char *this; ListP lp = NULL; int dup = 0; if (argc < 2) { fprintf(stderr, "Usage: fread \n"); exit(-1); } inFile = fopen(argv[1], "r"); while ((this = getword()) != (char*) EOF) { if (isMember(this, lp)) { dup++; ungetword(); } else lp = addLast(this, lp); } printf("The list is\n"); printlist(lp); printf("The list has length %d\n", length(lp)); printf("The reversed list is\n"); printlist(reverse(lp)); printf("There were %d repeats\n", dup); printf("I needed %d bytes to store the words\n", (thisword - wordsbuffer)); }