/* * Copyright 2012 Steven Gribble * * This file is part of the UW CSE 333 course project sequence * (333proj). * * 333proj is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * 333proj is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with 333proj. If not, see . */ #include #include #include #include #include "./HashTable.h" // What we are storing as the value in our hashtable. typedef struct word_count_st { char *word; unsigned int count; } WordCount; // Print the usage message to STDERR and exit(EXIT_FAILURE); void Usage(void); // Reads the file into memory, allocating sufficient space // for the file as it goes. Returns NULL on failure, non-NULL // on success. char *ReadFileIntoMemory(char *filename); // Insert a word into the hashtable. Returns 0 on failure, // 1 on success. int InsertWordIntoHashTable(HashTable ht, char *word); int main(int argc, char **argv) { if (argc != 2) Usage(); // Read in the file content. char *fdata = ReadFileIntoMemory(argv[1]); if (fdata == NULL) Usage(); // Create a hashtable. HashTable ht = AllocateHashTable(1); // Split the file up into tokens. char *tok = strtok(fdata, " \r\n\t"); while (tok != NULL) { // Convert the word to lower-case. for (int i=0; icount, wc->word); HTIteratorNext(it); } // Clean up and exit. HTIteratorFree(it); free(fdata); FreeHashTable(ht, &free); return EXIT_SUCCESS; } void Usage(void) { fprintf(stderr, "usage: word_count filename\n"); exit(EXIT_FAILURE); } char *ReadFileIntoMemory(char *filename) { // Try to open the file. FILE *f = fopen(filename, "rb"); if (f == NULL) return NULL; // Figure out how big the file is. long fsize; if (fseek(f, 0, SEEK_END) == -1) { fclose(f); return NULL; } fsize = ftell(f); if (fsize < 0) { fclose(f); return NULL; } if (fseek(f, 0, SEEK_SET) == -1) { fclose(f); return NULL; } // Allocate space for the file. char *retval = (char *) malloc(sizeof(char) * (fsize + 1)); if (retval == NULL) { fclose(f); return NULL; } // Read the file into memory. size_t readval = fread(retval, fsize, 1, f); if (readval != 1) { fclose(f); free(retval); return NULL; } // NULL-terminate the file data. retval[fsize] = '\0'; // Clean up. fclose(f); return retval; } int InsertWordIntoHashTable(HashTable ht, char *word) { HTKeyValue kv, oldkv; // Test to see if the word is already in the HT. if (LookupHashTable(ht, FNVHash64((unsigned char *) word, strlen(word)), &kv) == 1) { WordCount *wc = (WordCount *) kv.value; wc->count += 1; return 1; } // Allocate a WordCount to store the word. WordCount *wc = (WordCount *) malloc(sizeof(WordCount)); if (wc == NULL) { return 0; } // Prep the WordCount and insert it. wc->word = word; wc->count = 1; kv.key = FNVHash64((unsigned char *) word, strlen(word)); kv.value = (void *) wc; if (InsertHashTable(ht, kv, &oldkv) != 1) { free(wc); return 0; } // All done! return 1; }