uthash宏测试程序示例
创始人
2024-06-03 10:31:57
0

以下是一个测试uthash宏的测试程序:

用以下一个测试程序uthash_test.c,对uthash中宏进行封装:

1) 定义了一个使用uthash的结构体MY_STRUCT,注意这个结构体中包含了一个类型为UT_hash_handle hh的变量,它使得这个结构体可哈希。

2) int add_users(int user_id, const char * name):先用传入的user_id作为键在哈希表中查找,如果找到了对应的结构体,则用传入的name中字符串替换所找到结构体中的name成员变量的值,如果没有找到,则分配一个MY_STRUCT结构体,把user_id, name的值赋给新创建结构体中对应的成员变量,并用user_id作为键,把这个结构体添加到哈希表中。

3) MY_STRUCT * find_users(int user_id):根据传入user_id作为键,查找哈希表中对应键值的结构体是否存在, 若存在,则返回这个结构体指针,否则返回NULL。

4) void delete_user(MY_STRUCT * user):从哈希表users中删除user指向的结构体,并且释放user指向的结构体。

5) void delete_all():从哈希表users中删除并且释放所有MY_STRUCT结构体。

6) void print_users():从哈希表中逐个取出结构体,并且格式化输出这个结构体

7)int by_name(const MY_STRUCT * a, const MY_STRUCT * b):用于排序时,按结构体中name字段排序。

8)int by_id(const MY_STRUCT * a, const MY_STRUCT * b):在哈希表中排序时,使用的按结构体的id字段排序

9) const char * getl(const char * prompt):  使用传入的字符串打印提示符, 并且从标准输入读取一个字符串, 放入内部缓存,并且返回这个缓存地址。

#include 
#include 
#include 
#include "uthash.h"
#include "uthash_test.h"// 把以下结构体移动到新定义的头文件中
/*
typedef struct my_struct{int id;                         char name[21];                 UT_hash_handle hh;             
}MY_STRUCT;
*//*  向哈希表添加结构体,并且根据是否添加,返回0或-1 */
int add_users(int user_id, const char * name)
{MY_STRUCT * s;/* * 使用传入的user_id变量作为见来查找这个结构体,并且如果找到,使用s指向这个这个* 结构体,否则s指向NULL* */HASH_FIND_INT(users, &user_id, s);if (s == NULL){/* 如果没有找到,则分配一个MY_STRUCT结构体空间把传入的user_id赋给这个结构的id成员,传入的name复制到name成员 */s = (MY_STRUCT *)malloc(sizeof(MY_STRUCT));s->id = user_id;strcpy(s->name, name);/** 通过键名id添加由s指向的结构体到哈希表users* */HASH_ADD_INT(users, id, s);return 0;}else{/* 如果在哈希表中已经存在了这个键,则替换找到结构中name成员 */strcpy(s->name, name);return -1;}
}/* 根据传入user_id作为键,查找哈希表中对应键值的结构体是否存在, 若存在,则返回这个结构体指针,否则返回NULL */
MY_STRUCT * find_users(int user_id)
{MY_STRUCT *s;/** 使用user_id作为键在哈希表中查找结构体,s将指向这个结构体,并且返回这个指针* */HASH_FIND_INT(users, &user_id, s);return s;
}/* 从哈希表users中删除user指向的结构体,并且释放user指向的结构体 */
void delete_user(MY_STRUCT * user)
{/* 从哈希表users删除由user指向的结构体,它不会删除user指向的结构体 */HASH_DEL(users, user);free(user);
}/*从哈希表users中删除并且释放所有MY_STRUCT结构体
*/
void delete_all()
{MY_STRUCT * current_user;MY_STRUCT * tmp;/** HASH_ITER宏函数的成员(hh_name, head, item_ptr, tmp_item_ptr)* 使得结构体可哈希的成员名称,哈希表头,获取的当前结构体指针,临时指针* */HASH_ITER(hh, users, current_user, tmp){HASH_DEL(users, current_user);free(current_user);}
}/* 从哈希表中逐个取出结构体,并且格式化输出这个结构体 */
void print_users()
{MY_STRUCT *s;for (s = users;  s != NULL; s = (MY_STRUCT *)(s->hh.next)){printf("user id %4d: name %20s\n", s->id, s->name);}
}/* 在哈希表中排序时,使用的按名称排序 */
int by_name(const MY_STRUCT * a, const MY_STRUCT * b)
{return strcmp(a->name, b->name);
}/* 在哈希表中排序时,使用的按id排序 */
int by_id(const MY_STRUCT * a, const MY_STRUCT * b)
{return a->id > b->id;
}/*  使用传入的字符串打印提示符, 并且从标准输入读取一个字符串, 放入内部缓存,并且返回这个缓存地址  */
const char * getl(const char * prompt)
{static char buf[21];char * p;// 使用传入的字符串打印提示符printf("%s? ", prompt);fflush(stdout);/* 从标准输入读取一行,放入buf中 */p = fgets(buf, sizeof(buf), stdin);/* 如果输入为空,或者输入不为\n结尾则退出  */if (p == NULL || (p = strchr(buf, '\n')) == NULL){puts("Invalid intput!");exit(EXIT_FAILURE);}// 将缓存中输入串的末尾的\n替换为\0* p = '\0';return buf;
}

 

编辑一个以上函数组成的头文件,并且定义一个全局变量users,作为哈希表头:

#include 
#include 
#include 
#include "uthash.h"#ifndef _UTHASH_TEST_H_
#define _UTHASH_TEST_H_typedef struct my_struct{int id;                         /* 键 */char name[21];                  /* 值 */UT_hash_handle hh;              /* 使得这个结构体可以哈希 */
}MY_STRUCT;MY_STRUCT * users;int add_users(int user_id, const char * name);
MY_STRUCT * find_users(int user_id);
void delete_user(MY_STRUCT * user);
void delete_all();
void print_users();
int by_name(const MY_STRUCT * a, const MY_STRUCT * b);
int by_id(const MY_STRUCT * a, const MY_STRUCT * b);
const char * getl(const char * prompt);#endif

以下一个测试主程序main.c:

#include 
#include 
#include 
#include "uthash.h"
#include "uthash_test.h"extern MY_STRUCT * users;int main(int argc, char ** argv)
{int id = 1;int running = 1;MY_STRUCT * s;int temp;// 在输入running变成1前,一直运行while (running){printf(" 1. add user\n");printf(" 2. add or rename user by id\n");printf(" 3. find user\n");printf(" 4. delete user\n");printf(" 5. delete all users\n");printf(" 6. sort items by name\n");printf(" 7. sort items by id\n");printf(" 8. print users\n");printf(" 9. count users\n");printf(" 10. quit\n");// 获取输入值,将其转换成整数switch(atoi(getl("Command"))){case 1:// 根据id,添加结构体add_users(id++, getl("Name (20 char max)"));break;case 2:// 根据输入id,如果id存在,更改结构体中name成员变量// 如果不存在,则用这个id产生一个结构体,并让id作为键// 将结构体添加如哈希表temp = atoi(getl("ID"));add_users(temp, getl("Name (20 char max)"));break;case 3:// 根据输入id作为键,查找结构体,并且如果找到,则输出//这个结构体的name变量的内容,否则输出unknown。s = find_users(atoi(getl("ID to find")));printf("user: %s\n", s ? s->name : "unknown");break;case 4:// 根据id为键,查找到对应的结构体,将其从哈希表中删除,并释放这个结构体s = find_users(atoi(getl("ID to delete")));if (s){delete_user(s);}else{printf("id unknown\n");}break;// 删除哈希表中所有结构体,并且释放这些结构体case 5:delete_all();break;case 6:// 哈希表按name成员变量排序HASH_SORT(users, by_name);break;case 7:// 哈希表按id成员变量排序HASH_SORT(users, by_id);break;case 8:// 输出哈希表中所有结构体print_users();break;case 9:// 计算哈希表中结构体数目temp = HASH_COUNT(users);printf("there are %d\n", temp);break;case 10:// 退出程序running = 0;break;}}// 退出程序前,从哈希表中删除所有结构体,并释放这些结构体delete_all();return 0;
}

编译以上程序,生成主程序main:

[blctrl@rockygu uthash]$ gcc main.c uthash_test.c -o main

对主程序main进行进行测试:

[blctrl@rockygu uthash]$ ./main1. add user2. add or rename user by id3. find user4. delete user5. delete all users6. sort items by name7. sort items by id8. print users9. count users10. quit
Command? 1
Name (20 char max)? hello1. add user2. add or rename user by id3. find user4. delete user5. delete all users6. sort items by name7. sort items by id8. print users9. count users10. quit
Command? 1
Name (20 char max)? good1. add user2. add or rename user by id3. find user4. delete user5. delete all users6. sort items by name7. sort items by id8. print users9. count users10. quit
Command? 1
Name (20 char max)? at1. add user2. add or rename user by id3. find user4. delete user5. delete all users6. sort items by name7. sort items by id8. print users9. count users10. quit
Command? 8
user id    1: name                hello
user id    2: name                 good
user id    3: name                   at1. add user2. add or rename user by id3. find user4. delete user5. delete all users6. sort items by name7. sort items by id8. print users9. count users10. quit
Command? 61. add user2. add or rename user by id3. find user4. delete user5. delete all users6. sort items by name7. sort items by id8. print users9. count users10. quit
Command? 8
user id    3: name                   at
user id    2: name                 good
user id    1: name                hello1. add user2. add or rename user by id3. find user4. delete user5. delete all users6. sort items by name7. sort items by id8. print users9. count users10. quit
Command? 71. add user2. add or rename user by id3. find user4. delete user5. delete all users6. sort items by name7. sort items by id8. print users9. count users10. quit
Command? 8
user id    1: name                hello
user id    2: name                 good
user id    3: name                   at1. add user2. add or rename user by id3. find user4. delete user5. delete all users6. sort items by name7. sort items by id8. print users9. count users10. quit
Command? 4
ID to delete? 21. add user2. add or rename user by id3. find user4. delete user5. delete all users6. sort items by name7. sort items by id8. print users9. count users10. quit
Command? 8
user id    1: name                hello
user id    3: name                   at1. add user2. add or rename user by id3. find user4. delete user5. delete all users6. sort items by name7. sort items by id8. print users9. count users10. quit
Command? 9
there are 21. add user2. add or rename user by id3. find user4. delete user5. delete all users6. sort items by name7. sort items by id8. print users9. count users10. quit
Command? 10

相关内容

热门资讯

监控摄像头接入GB28181平... 流程简介将监控摄像头的视频在网站和APP中直播,要解决的几个问题是:1&...
Windows10添加群晖磁盘... 在使用群晖NAS时,我们需要通过本地映射的方式把NAS映射成本地的一块磁盘使用。 通过...
protocol buffer... 目录 目录 什么是protocol buffer 1.protobuf 1.1安装  1.2使用...
Fluent中创建监测点 1 概述某些仿真问题,需要创建监测点,用于获取空间定点的数据࿰...
educoder数据结构与算法...                                                   ...
MySQL下载和安装(Wind... 前言:刚换了一台电脑,里面所有东西都需要重新配置,习惯了所...
MFC文件操作  MFC提供了一个文件操作的基类CFile,这个类提供了一个没有缓存的二进制格式的磁盘...
在Word、WPS中插入AxM... 引言 我最近需要写一些文章,在排版时发现AxMath插入的公式竟然会导致行间距异常&#...
有效的括号 一、题目 给定一个只包括 '(',')','{','}'...
【Ctfer训练计划】——(三... 作者名:Demo不是emo  主页面链接:主页传送门 创作初心ÿ...