#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
#define K 1024
#define CHUNK 8
char **read_dictionary(int *r_len);
bool word_lookup(char *word, char **dict, int dict_len);
int main(int argc, char *argv[]) {
FILE *fd;
char **dictionary;
char buffer[K];
int dict_len = 0;
// Make sure they pass one command line argument, path to file
if(argc != 2) {
fprintf(stderr, "Usage: %s <text-file>\n", argv[0]);
exit(1);
}
// Open the file they gave us
fd = fopen(argv[1], "r");
if(fd == NULL) {
fprintf(stderr, "Error: Unable to open file %s for reading.\n", argv[1]);
exit(1);
}
// Reading the dictionary
dictionary = read_dictionary(&dict_len);
if(dictionary == NULL) {
exit(1);
}
// Lookup the words
while(fscanf(fd, "%s", buffer) == 1) {
if(word_lookup(buffer, dictionary, dict_len) == false) {
printf("%s\n", buffer);
}
}
return 0;
}
char **read_dictionary(int *r_len)
{
FILE *fd;
char **dict = NULL;
int len = 0, cap = 0;
char buffer[K];
fd = fopen("/usr/dict/words", "r");
if(fd == NULL) {
fprintf(stderr, "Error: Unable to read dictionary file.\n");
return NULL;
}
while(fgets(buffer, K, fd) != NULL) {
// Removing that pesky newline
int index = strlen(buffer) - 1;
if(buffer[index] == '\n') {
buffer[index] = '\0';
}
// Add the word to my array
if(len > cap - 1) {
// Out of space
cap = (cap == 0) ? CHUNK : cap * 2;
dict = realloc(dict, cap * sizeof(char *));
}
dict[len++] = strdup(buffer);
}
(*r_len) = len;
return dict;
}
bool word_lookup(char *word, char **dict, int dict_len)
{
int lo = 0;
int hi = dict_len - 1;
while(lo <= hi) {
int mid = (hi + lo) / 2;
int rv = strcasecmp(word, dict[mid]);
if(rv == 0) {
return true;
} else if(rv < 0) {
hi = mid - 1;
} else {
lo = mid + 1;
}
}
return false;
}