Advertisement
dtung

dup.c

Apr 29th, 2020
787
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 1.83 KB | None | 0 0
  1. #define _GNU_SOURCE
  2. #include <stdio.h>
  3. #include <string.h>
  4. #include <stdlib.h>
  5. #include <search.h>
  6. #include <errno.h>
  7.  
  8. #define HASH_SIZE 1000
  9. #define LINE_SIZE 512
  10.  
  11. /* define client data */
  12. typedef struct client {
  13.     int count;
  14. } CLIENT;
  15.  
  16. /* duplicate client data */
  17. CLIENT *datadup(CLIENT *data) {
  18.     CLIENT *r = malloc(sizeof(CLIENT));
  19.     if (r == NULL) return NULL;
  20.     *r = *data;
  21.     return r;
  22. }
  23.  
  24. /* free dynamic allocated entry */
  25. void free_entry(ENTRY *e) {
  26.     if (e == NULL) return;
  27.     free(e->key);
  28.     free(e->data);
  29. }
  30.  
  31. int main() {
  32.     int hindex = 0;
  33.     char key[LINE_SIZE];
  34.     ENTRY map[HASH_SIZE];
  35.     struct hsearch_data htab = {};
  36.  
  37.     /* create hash map */
  38.     hcreate_r(HASH_SIZE, &htab);
  39.     ENTRY *rep;
  40.     /* run through key */
  41.     while (fgets(key, LINE_SIZE, stdin) > 0) {
  42.         /* construct entry */
  43.         CLIENT data = {.count = 1};
  44.         ENTRY e = {.key = strdup(key), .data = datadup(&data)};
  45.         /* check entry */
  46.         if (hsearch_r(e, FIND, &rep, &htab)) {
  47.             /* update data */
  48.             if (rep != NULL) {
  49.                 CLIENT *cp = rep->data;
  50.                 cp->count++;
  51.             }
  52.             free_entry(&e);
  53.         } else {
  54.             /* enter entry */
  55.             if (hsearch_r(e, ENTER, &rep, &htab) && hindex < HASH_SIZE) {  
  56.                 map[hindex++] = e;
  57.             } else {
  58.                 fprintf(stderr, "increase HASH_SIZE: %s\n", strerror(errno));
  59.                 exit(1);
  60.             }
  61.         }
  62.     }
  63.  
  64.     /* print hash */
  65.     for (int i = 0; i < hindex; i++) {
  66.         CLIENT *cp = map[i].data;
  67.         if (cp->count > 1)
  68.             printf("%3d %s", cp->count, map[i].key);
  69.     }
  70.     /* free entries */
  71.     for (int i = 0; i < hindex; i++)
  72.         free_entry(&map[i]);
  73.  
  74.     hdestroy_r(&htab);
  75.     exit(0);
  76. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement