Advertisement
drankinatty

Word Search mmap'ed File

Dec 14th, 2019
282
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 3.02 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <ctype.h>
  5. #include <errno.h>
  6. #include <fcntl.h>
  7. #include <limits.h>
  8. #include <sys/mman.h>
  9. #include <sys/stat.h>
  10. #include <sys/types.h>
  11. #include <unistd.h>
  12.  
  13. #define MAX_WORD_LENGTH 32
  14.  
  15. int main (int argc, char **argv) {
  16.    
  17.     int ifd;                /* input file descriptor */
  18.     struct stat ss = {0};   /* struct stat */
  19.     off_t   offset = 0,     /* offset from start of file */
  20.                             /* multiple of page-size in mapped file */
  21.             pa_offset = offset & ~(sysconf (_SC_PAGE_SIZE) - 1);
  22.     char *fptr = NULL;      /* pointer to content in memory mapped file */
  23.  
  24.     if (argc < 2 ) {    /* validate 1 argument given for filename */
  25.         fprintf (stderr, "error: insufficient input,\n"
  26.                          "usage: %s filename\n", argv[0]);
  27.         return 1;
  28.     }
  29.    
  30.     /* open file read-only/validate file open for reading */
  31.     if ((ifd = open (argv[1], O_RDONLY)) == -1) {
  32.         perror ("open-argv[1]");
  33.         return 1;
  34.     }
  35.    
  36.     if (fstat (ifd, &ss) == -1) { /* fill/validate stat struct for file size */
  37.         perror ("fstat-ifd");
  38.         return 1;
  39.     }
  40.    
  41.     /* mmap file to fptr/validate mapping succeeded */
  42.     if ((fptr = mmap (NULL, ss.st_size + offset - pa_offset, PROT_READ,
  43.                       MAP_SHARED, ifd, pa_offset)) == (void *)-1) {
  44.         perror ("mmap-ifd");
  45.         return 1;
  46.     }
  47.    
  48.     for (;;) {  /* loop continually allowing user to enter searches */
  49.         char word[MAX_WORD_LENGTH + 1] = "",    /* buffer to hold word */
  50.             *p = fptr;                          /* pointer to mmaped content */
  51.         size_t  count = 0,                      /* no. time word found */
  52.                 len = 0;                        /* word length */
  53.        
  54.         /* prompt for word to search, read/validate input */
  55.         fputs ("\nenter word (zzz to quit): ", stdout);
  56.         if (!fgets (word, sizeof word, stdin) || strncmp (word, "zzz", 3) == 0)
  57.             break;
  58.        
  59.         word[(len = strcspn(word, "\n"))] = 0;  /* trim \n from end, get len */
  60.        
  61.         while ((p = strstr (p, word))) {    /* loop finding each match */
  62.             /* if ((at beginning or prev char is space or punct) ||
  63.              *     (or next char after word is end, space or punct))
  64.              */
  65.             if (((p == fptr) ||
  66.                 (p > fptr && (isspace(*(p - 1)) || ispunct(*(p - 1))))) &&
  67.                 (!*(p + len) || isspace(*(p + len)) || ispunct(*(p + len))))
  68.                 count++;    /* increment count */
  69.             p += len;       /* advance pointer to next after word */
  70.         }
  71.        
  72.         if (count)  /* if count not zero, output count - or not found */
  73.             printf ("'%s' was found %zu times.\n", word, count);
  74.         else
  75.             printf ("word not found: '%s'.\n", word);
  76.     }
  77.    
  78.     munmap (fptr, ss.st_size);  /* unmap file */
  79.     close (ifd);                /* close file descriptor */
  80. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement