mroker

Untitled

Jul 28th, 2017
37
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 5.12 KB | None | 0 0
  1. /**
  2.  * Implements a spell-checker.
  3.  */
  4.  
  5. #include <ctype.h>
  6. #include <stdio.h>
  7. #include <sys/resource.h>
  8. #include <sys/time.h>
  9.  
  10. #include "dictionary.h"
  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.     // structs 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
  36.     char* dictionary = (argc == 3) ? argv[1] : DICTIONARY;
  37.  
  38.     // load dictionary
  39.     getrusage(RUSAGE_SELF, &before);
  40.     bool loaded = load(dictionary);
  41.     getrusage(RUSAGE_SELF, &after);
  42.  
  43.     // abort if dictionary not loaded
  44.     if (!loaded)
  45.     {
  46.         printf("Could not load %s.\n", dictionary);
  47.         return 1;
  48.     }
  49.  
  50.     // calculate time to load dictionary
  51.     time_load = calculate(&before, &after);
  52.  
  53.     // try to open text
  54.     char *text = (argc == 3) ? argv[2] : argv[1];
  55.     FILE *fp = fopen(text, "r");
  56.     if (fp == NULL)
  57.     {
  58.         printf("Could not open %s.\n", text);
  59.         unload();
  60.         return 1;
  61.     }
  62.  
  63.     // prepare to report misspellings
  64.     printf("\nMISSPELLED WORDS\n\n");
  65.  
  66.     // prepare to spell-check
  67.     int index = 0, misspellings = 0, words = 0;
  68.     char word[LENGTH+1];
  69.  
  70.     // spell-check each word in text
  71.     for (int c = fgetc(fp); c != EOF; c = fgetc(fp))
  72.     {
  73.         // allow only alphabetical characters and apostrophes
  74.         if (isalpha(c) || (c == '\'' && index > 0))
  75.         {
  76.             // append character to word
  77.             word[index] = c;
  78.             index++;
  79.  
  80.             // ignore alphabetical strings too long to be words
  81.             if (index > LENGTH)
  82.             {
  83.                 // consume remainder of alphabetical string
  84.                 while ((c = fgetc(fp)) != EOF && isalpha(c));
  85.  
  86.                 // prepare for new word
  87.                 index = 0;
  88.             }
  89.         }
  90.  
  91.         // ignore words with numbers (like MS Word can)
  92.         else if (isdigit(c))
  93.         {
  94.             // consume remainder of alphanumeric string
  95.             while ((c = fgetc(fp)) != EOF && isalnum(c));
  96.  
  97.             // prepare for new word
  98.             index = 0;
  99.         }
  100.  
  101.         // we must have found a whole word
  102.         else if (index > 0)
  103.         {
  104.             // terminate current word
  105.             word[index] = '\0';
  106.  
  107.             // update counter
  108.             words++;
  109.  
  110.             // check word's spelling
  111.             getrusage(RUSAGE_SELF, &before);
  112.             bool misspelled = !check(word);
  113.             getrusage(RUSAGE_SELF, &after);
  114.  
  115.             // update benchmark
  116.             time_check += calculate(&before, &after);
  117.  
  118.             // print word if misspelled
  119.             if (misspelled)
  120.             {
  121.                 printf("%s\n", word);
  122.                 misspellings++;
  123.             }
  124.  
  125.             // prepare for next word
  126.             index = 0;
  127.         }
  128.     }
  129.  
  130.     // check whether there was an error
  131.     if (ferror(fp))
  132.     {
  133.         fclose(fp);
  134.         printf("Error reading %s.\n", text);
  135.         unload();
  136.         return 1;
  137.     }
  138.  
  139.     // close text
  140.     fclose(fp);
  141.  
  142.     // determine dictionary's size
  143.     getrusage(RUSAGE_SELF, &before);
  144.     unsigned int n = size();
  145.     getrusage(RUSAGE_SELF, &after);
  146.  
  147.     // calculate time to determine dictionary's size
  148.     time_size = calculate(&before, &after);
  149.  
  150.     // unload dictionary
  151.     getrusage(RUSAGE_SELF, &before);
  152.     bool unloaded = unload();
  153.     getrusage(RUSAGE_SELF, &after);
  154.  
  155.     // abort if dictionary not unloaded
  156.     if (!unloaded)
  157.     {
  158.         printf("Could not unload %s.\n", dictionary);
  159.         return 1;
  160.     }
  161.  
  162.     // calculate time to unload dictionary
  163.     time_unload = calculate(&before, &after);
  164.  
  165.     // report benchmarks
  166.     printf("\nWORDS MISSPELLED:     %d\n", misspellings);
  167.     printf("WORDS IN DICTIONARY:  %d\n", n);
  168.     printf("WORDS IN TEXT:        %d\n", words);
  169.     printf("TIME IN load:         %.2f\n", time_load);
  170.     printf("TIME IN check:        %.2f\n", time_check);
  171.     printf("TIME IN size:         %.2f\n", time_size);
  172.     printf("TIME IN unload:       %.2f\n", time_unload);
  173.     printf("TIME IN TOTAL:        %.2f\n\n",
  174.      time_load + time_check + time_size + time_unload);
  175.  
  176.     // that's all folks
  177.     return 0;
  178. }
  179.  
  180. /**
  181.  * Returns number of seconds between b and a.
  182.  */
  183. double calculate(const struct rusage *b, const struct rusage *a)
  184. {
  185.     if (b == NULL || a == NULL)
  186.     {
  187.         return 0.0;
  188.     }
  189.     else
  190.     {
  191.         return ((((a->ru_utime.tv_sec * 1000000 + a->ru_utime.tv_usec) -
  192.                  (b->ru_utime.tv_sec * 1000000 + b->ru_utime.tv_usec)) +
  193.                 ((a->ru_stime.tv_sec * 1000000 + a->ru_stime.tv_usec) -
  194.                  (b->ru_stime.tv_sec * 1000000 + b->ru_stime.tv_usec)))
  195.                 / 1000000.0);
  196.     }
  197. }
Add Comment
Please, Sign In to add comment