Advertisement
bocajbee

speller.c

May 27th, 2020
126
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 5.38 KB | None | 0 0
  1. // Implements a spell-checker
  2.  
  3. #include <ctype.h>
  4. #include <stdio.h>
  5. #include <sys/resource.h>
  6. #include <sys/time.h>
  7.  
  8. #include "dictionary.h"
  9.  
  10. // Undefine any definitions
  11. #undef calculate
  12. #undef getrusage
  13.  
  14. // Default dictionary
  15. #define DICTIONARY "dictionaries/large"
  16.  
  17. // Prototype
  18. double calculate(const struct rusage *b, const struct rusage *a);
  19.  
  20. int main(int argc, char *argv[])
  21. {
  22.     // Check for correct number of args
  23.     if (argc != 2 && argc != 3)
  24.     {
  25.         printf("Usage: ./speller [DICTIONARY] text\n");
  26.         return 1;
  27.     }
  28.  
  29.     // Structures for timing data
  30.     struct rusage before, after;
  31.  
  32.     // Benchmarks
  33.     double time_load = 0.0, time_check = 0.0, time_size = 0.0, time_unload = 0.0;
  34.  
  35.     // Determine dictionary to use. if if the user has 3 args inputted at the command line ("./speller, their own dictionary, text file), use the dictionary they inputted at arg1, otherwise just default to using Dictionary/large to check against
  36.     char *dictionary = (argc == 3) ? argv[1] : DICTIONARY;
  37.  
  38.     // Load dictionary
  39.     getrusage(RUSAGE_SELF, &before);
  40.     bool loaded = load(dictionary);
  41.     print_words_list();
  42.     getrusage(RUSAGE_SELF, &after);
  43.  
  44.     // Exit if dictionary not loaded
  45.     if (!loaded)
  46.     {
  47.         printf("Could not load %s.\n", dictionary);
  48.         return 1;
  49.     }
  50.  
  51.     // Calculate time to load dictionary
  52.     time_load = calculate(&before, &after);
  53.  
  54.     // Try to open text
  55.     char *text = (argc == 3) ? argv[2] : argv[1];
  56.     FILE *file = fopen(text, "r");
  57.     if (file == NULL)
  58.     {
  59.         printf("Could not open %s.\n", text);
  60.         unload();
  61.         return 1;
  62.     }
  63.  
  64.     // Prepare to report misspellings
  65.     printf("\nMISSPELLED WORDS\n\n");
  66.  
  67.     // Prepare to spell-check
  68.     int index = 0, misspellings = 0, words = 0;
  69.     char word[LENGTH + 1];
  70.  
  71.     // Spell-check each word in text
  72.     for (int c = fgetc(file); c != EOF; c = fgetc(file))
  73.     {
  74.         // Allow only alphabetical characters and apostrophes
  75.         if (isalpha(c) || (c == '\'' && index > 0))
  76.         {
  77.             // Append character to word
  78.             word[index] = c;
  79.             index++;
  80.  
  81.             // Ignore alphabetical strings too long to be words
  82.             if (index > LENGTH)
  83.             {
  84.                 // Consume remainder of alphabetical string
  85.                 while ((c = fgetc(file)) != EOF && isalpha(c));
  86.  
  87.                 // Prepare for new word
  88.                 index = 0;
  89.             }
  90.         }
  91.  
  92.         // Ignore words with numbers (like MS Word can)
  93.         else if (isdigit(c))
  94.         {
  95.             // Consume remainder of alphanumeric string
  96.             while ((c = fgetc(file)) != EOF && isalnum(c));
  97.  
  98.             // Prepare for new word
  99.             index = 0;
  100.         }
  101.  
  102.         // We must have found a whole word
  103.         else if (index > 0)
  104.         {
  105.             // Terminate current word
  106.             word[index] = '\0';
  107.  
  108.             // Update counter
  109.             words++;
  110.  
  111.             // Check word's spelling
  112.             getrusage(RUSAGE_SELF, &before);
  113.             bool misspelled = !check(word);
  114.             getrusage(RUSAGE_SELF, &after);
  115.  
  116.             // Update benchmark
  117.             time_check += calculate(&before, &after);
  118.  
  119.             // Print word if misspelled
  120.             if (misspelled)
  121.             {
  122.                 printf("%s\n", word);
  123.                 misspellings++;
  124.             }
  125.  
  126.             // Prepare for next word
  127.             index = 0;
  128.         }
  129.     }
  130.  
  131.     // Check whether there was an error
  132.     if (ferror(file))
  133.     {
  134.         fclose(file);
  135.         printf("Error reading %s.\n", text);
  136.         unload();
  137.         return 1;
  138.     }
  139.  
  140.     // Close text
  141.     fclose(file);
  142.  
  143.     // Determine dictionary's size
  144.     getrusage(RUSAGE_SELF, &before);
  145.     unsigned int n = size();
  146.     getrusage(RUSAGE_SELF, &after);
  147.  
  148.     // Calculate time to determine dictionary's size
  149.     time_size = calculate(&before, &after);
  150.  
  151.     // Unload dictionary
  152.     getrusage(RUSAGE_SELF, &before);
  153.     bool unloaded = unload();
  154.     getrusage(RUSAGE_SELF, &after);
  155.  
  156.     // Abort if dictionary not unloaded
  157.     if (!unloaded)
  158.     {
  159.         printf("Could not unload %s.\n", dictionary);
  160.         return 1;
  161.     }
  162.  
  163.     // Calculate time to unload dictionary
  164.     time_unload = calculate(&before, &after);
  165.  
  166.     // Report benchmarks
  167.     printf("\nWORDS MISSPELLED:     %d\n", misspellings);
  168.     printf("WORDS IN DICTIONARY:  %d\n", n);
  169.     printf("WORDS IN TEXT:        %d\n", words);
  170.     printf("TIME IN load:         %.2f\n", time_load);
  171.     printf("TIME IN check:        %.2f\n", time_check);
  172.     printf("TIME IN size:         %.2f\n", time_size);
  173.     printf("TIME IN unload:       %.2f\n", time_unload);
  174.     printf("TIME IN TOTAL:        %.2f\n\n",
  175.            time_load + time_check + time_size + time_unload);
  176.  
  177.     // Success
  178.     return 0;
  179. }
  180.  
  181. // Returns number of seconds between b and a
  182. double calculate(const struct rusage *b, const struct rusage *a)
  183. {
  184.     if (b == NULL || a == NULL)
  185.     {
  186.         return 0.0;
  187.     }
  188.     else
  189.     {
  190.         return ((((a->ru_utime.tv_sec * 1000000 + a->ru_utime.tv_usec) -
  191.                   (b->ru_utime.tv_sec * 1000000 + b->ru_utime.tv_usec)) +
  192.                  ((a->ru_stime.tv_sec * 1000000 + a->ru_stime.tv_usec) -
  193.                   (b->ru_stime.tv_sec * 1000000 + b->ru_stime.tv_usec)))
  194.                 / 1000000.0);
  195.     }
  196. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement