example.c 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. #include <stdio.h> /* printf */
  2. #include <stdlib.h> /* atoi, malloc */
  3. #include <string.h> /* strcpy */
  4. #include "uthash.h"
  5. struct my_struct {
  6. int id; /* key */
  7. char name[21];
  8. UT_hash_handle hh; /* makes this structure hashable */
  9. };
  10. struct my_struct *users = NULL;
  11. void add_user(int user_id, const char *name)
  12. {
  13. struct my_struct *s;
  14. HASH_FIND_INT(users, &user_id, s); /* id already in the hash? */
  15. if (s == NULL) {
  16. s = (struct my_struct*)malloc(sizeof *s);
  17. s->id = user_id;
  18. HASH_ADD_INT(users, id, s); /* id is the key field */
  19. }
  20. strcpy(s->name, name);
  21. }
  22. struct my_struct *find_user(int user_id)
  23. {
  24. struct my_struct *s;
  25. HASH_FIND_INT(users, &user_id, s); /* s: output pointer */
  26. return s;
  27. }
  28. void delete_user(struct my_struct *user)
  29. {
  30. HASH_DEL(users, user); /* user: pointer to deletee */
  31. free(user);
  32. }
  33. void delete_all()
  34. {
  35. struct my_struct *current_user;
  36. struct my_struct *tmp;
  37. HASH_ITER(hh, users, current_user, tmp) {
  38. HASH_DEL(users, current_user); /* delete it (users advances to next) */
  39. free(current_user); /* free it */
  40. }
  41. }
  42. void print_users()
  43. {
  44. struct my_struct *s;
  45. for (s = users; s != NULL; s = (struct my_struct*)(s->hh.next)) {
  46. printf("user id %d: name %s\n", s->id, s->name);
  47. }
  48. }
  49. int by_name(const struct my_struct *a, const struct my_struct *b)
  50. {
  51. return strcmp(a->name, b->name);
  52. }
  53. int by_id(const struct my_struct *a, const struct my_struct *b)
  54. {
  55. return (a->id - b->id);
  56. }
  57. const char *getl(const char *prompt)
  58. {
  59. static char buf[21];
  60. char *p;
  61. printf("%s? ", prompt); fflush(stdout);
  62. p = fgets(buf, sizeof(buf), stdin);
  63. if (p == NULL || (p = strchr(buf, '\n')) == NULL) {
  64. puts("Invalid input!");
  65. exit(EXIT_FAILURE);
  66. }
  67. *p = '\0';
  68. return buf;
  69. }
  70. int main()
  71. {
  72. int id = 1;
  73. int running = 1;
  74. struct my_struct *s;
  75. int temp;
  76. while (running) {
  77. printf(" 1. add user\n");
  78. printf(" 2. add or rename user by id\n");
  79. printf(" 3. find user\n");
  80. printf(" 4. delete user\n");
  81. printf(" 5. delete all users\n");
  82. printf(" 6. sort items by name\n");
  83. printf(" 7. sort items by id\n");
  84. printf(" 8. print users\n");
  85. printf(" 9. count users\n");
  86. printf("10. quit\n");
  87. switch (atoi(getl("Command"))) {
  88. case 1:
  89. add_user(id++, getl("Name (20 char max)"));
  90. break;
  91. case 2:
  92. temp = atoi(getl("ID"));
  93. add_user(temp, getl("Name (20 char max)"));
  94. break;
  95. case 3:
  96. s = find_user(atoi(getl("ID to find")));
  97. printf("user: %s\n", s ? s->name : "unknown");
  98. break;
  99. case 4:
  100. s = find_user(atoi(getl("ID to delete")));
  101. if (s) {
  102. delete_user(s);
  103. } else {
  104. printf("id unknown\n");
  105. }
  106. break;
  107. case 5:
  108. delete_all();
  109. break;
  110. case 6:
  111. HASH_SORT(users, by_name);
  112. break;
  113. case 7:
  114. HASH_SORT(users, by_id);
  115. break;
  116. case 8:
  117. print_users();
  118. break;
  119. case 9:
  120. temp = HASH_COUNT(users);
  121. printf("there are %d users\n", temp);
  122. break;
  123. case 10:
  124. running = 0;
  125. break;
  126. }
  127. }
  128. delete_all(); /* free any structures */
  129. return 0;
  130. }