Determine if a word is spelled correctly

This commit is contained in:
Nick Chambers 2024-05-06 14:17:08 -05:00
parent 5bf1c56f54
commit e4726b87dd
1 changed files with 108 additions and 0 deletions

108
c/spellcheck.c Normal file
View File

@ -0,0 +1,108 @@
#include <ctype.h>
#include <errno.h>
#include <fcntl.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>
#include <unistd.h>
#define DICTIONARY "/usr/share/dict/words"
struct trie {
struct trie *children[26];
};
void new_trie(struct trie *tree) {
uint8_t idx = 0;
for(; idx < 26; idx += 1) {
tree->children[idx] = NULL;
}
}
void trie_insert(struct trie *tree, const char *str, uint8_t len) {
struct trie *node = tree;
uint8_t idx = 0;
for(; idx < len; idx += 1) {
uint8_t pos = tolower(str[idx]) - 'a';
if(node->children[pos] == NULL) {
void *mem = malloc(sizeof(struct trie));
if(mem == NULL) {
fprintf(stderr, "could not allocate memory: %s\n", strerror(errno));
exit(1);
}
node->children[pos] = mem;
new_trie(node->children[pos]);
}
node = node->children[pos];
}
}
uint8_t trie_has(struct trie *tree, const char *str, uint8_t len) {
struct trie *node = tree;
uint8_t idx = 0;
for(; idx < len; idx += 1) {
uint8_t pos = tolower(str[idx]) - 'a';
if(node->children[pos] == NULL) {
return 0;
}
node = node->children[pos];
}
return 1;
}
int main(int argc, char **argv) {
struct trie dict;
new_trie(&dict);
int fd = open(DICTIONARY, O_RDONLY);
if(fd < 0) {
fprintf(stderr, "could not open %s: %s\n", DICTIONARY, strerror(errno));
return 1;
}
ssize_t bytes = 0;
char buf[1024] = { 0 };
char word[128] = { 0 };
uint8_t len = 0;
while((bytes = read(fd, buf, sizeof(buf))) > 0) {
ssize_t idx = 0;
for(; idx < bytes; idx += 1) {
if(buf[idx] == '\n') {
trie_insert(&dict, word, len);
len = 0;
bzero(word, sizeof(word));
} else if(len < sizeof(word)) {
word[len] = buf[idx];
len += 1;
}
}
}
if(bytes < 0) {
fprintf(stderr, "could not read from %s: %s\n", DICTIONARY, strerror(errno));
return 1;
}
const char *check = "paladin";
if(argc > 1) {
check = argv[1];
}
return !trie_has(&dict, check, strlen(check));
}