简单的基于sqlite的服务器和客户端实现

打印 上一主题 下一主题

主题 1904|帖子 1904|积分 5712

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

x
server.c
  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <unistd.h>
  4. #include <stdlib.h>
  5. #include <sys/types.h>
  6. #include <sys/stat.h>
  7. #include <fcntl.h>
  8. #include <pthread.h>
  9. #include <semaphore.h>
  10. #include <wait.h>
  11. #include <signal.h>
  12. #include <sys/socket.h>
  13. #include <arpa/inet.h>
  14. #include <sys/ipc.h>
  15. #include <sys/sem.h>
  16. #include <semaphore.h>
  17. #include <sys/msg.h>
  18. #include <sys/shm.h>
  19. #include <sys/un.h>
  20. #include <sys/time.h>
  21. #include <sys/select.h>
  22. #include <sys/epoll.h>
  23. #include "doublyList.h
  24. "
  25. #include <sqlite3.h>
  26. #include "array.h
  27. "
  28. myListOP * fdList;
  29. int isSameAddr(void* a,void*b){
  30.     return a-b;
  31. }
  32. int isSameInt(int* a,int*b){
  33.     return *a-*b;
  34. }
  35. struct info{
  36.     struct sockaddr_in client_addr;
  37.     int fd;
  38.     struct epoll_event* event;
  39.     myListOP* record;
  40. };
  41. int* getfd(struct info* info){
  42.     return &(info->event->data.fd);
  43. }
  44. struct patientRecord
  45. {
  46.     time_t time;
  47.     char patientName[40];
  48.     char patientRec[128];
  49.     char doctorDia[128];
  50.     char tablet[128];
  51.     char doctorAdv[128];
  52.     //size=4*128+4+40=556
  53. };
  54. struct patientRecord * createPatinetRecord(time_t time,char* patientName,\
  55.                         char* patientRec,char* doctorDia,char* tablet,char* doctorAdv){
  56.                            struct patientRecord * ret = malloc (sizeof (struct patientRecord));
  57.                            ret->time = time;
  58.                            if (patientName)
  59.                            {
  60.                             strcpy(ret->patientName,patientName);
  61.                            }
  62.                            strcpy(ret->patientRec,patientRec);
  63.                            strcpy(ret->doctorDia,doctorDia);
  64.                            strcpy(ret->tablet,tablet);
  65.                            strcpy(ret->doctorAdv,doctorAdv);
  66.                            return ret;
  67.                         }
  68. enum enum_send_t{
  69.     send_record =1,
  70.     read_record,
  71. };
  72. struct send_t
  73. {
  74.     enum enum_send_t type;
  75.     struct patientRecord patientRecord;
  76. };
  77. static void printRec(struct patientRecord* rec){
  78.     char timeStr[64]; // 用于存储格式化后的时间字符串
  79.     strftime(timeStr, sizeof(timeStr), "%Y-%m-%d %H:%M:%S", localtime(&rec->time));
  80.     printf("%s::\n 病人描述:%s\n, 医生诊断:%s\n, 开药:%s\n, 医嘱:%s\n",
  81.            timeStr, rec->patientRec, rec->doctorDia, rec->tablet, rec->doctorAdv);
  82. }
  83. static void printSend_t(struct send_t* send){
  84.     if (send->type == send_record)
  85.     {
  86.         printf("send_record\n");
  87.     }
  88.         if (send->type == read_record)
  89.     {
  90.         printf("read_record\n");
  91.     }
  92.     printRec(&send->patientRecord);
  93. }
  94. struct info* creatInfo(struct sockaddr_in *client_addr,int fd,struct epoll_event* event){
  95.     struct info* ret = malloc(sizeof(struct info));
  96.     ret->record = myListDInit(printSend_t);
  97.     if (client_addr)
  98.     {
  99.         ret->client_addr=*client_addr;
  100.     }
  101.     else{
  102.         memset(&ret->client_addr,0,sizeof(struct sockaddr_in));
  103.     }
  104.     ret->event = event;
  105.     ret->fd = fd;
  106.     return ret;
  107. }
  108. void printInfo(struct info* info){
  109.     static char ip_human[16] = {0};
  110.     if (info ==0 || (&(info->client_addr)==0))
  111.     {
  112.         return;
  113.     }
  114.    
  115.     int port_human=ntohs(info->client_addr.sin_port);
  116.     inet_ntop(AF_INET,&info->client_addr.sin_addr,ip_human,16);
  117.     printf("ip:%s,port:%d,fd:%d::",ip_human,port_human,info->fd);
  118. }
  119. sqlite3* db;
  120. int mysqlite3_append(struct patientRecord* rec){
  121.     char sql[1024]="";
  122.     sprintf(sql,"create table if not exists %s (\
  123.         日期 INTEGER ,\
  124.         病人口述 TEXT,\
  125.         医生诊断 TEXT,\
  126.         医生开药 TEXT,\
  127.         医嘱 text \
  128.         );", rec->patientName);
  129.     char ** result;
  130.     char * errmsg;
  131.     int ret = 0;
  132.     ret=sqlite3_exec(db,sql,0,0,&errmsg);
  133.     if (ret)
  134.     {
  135.         //sql执行一场
  136.         printf("在添加表格时出现异常:: %s\n",errmsg);
  137.         return EXIT_FAILURE;
  138.     }
  139.     sprintf(sql,"insert into %s (日期,病人口述,医生诊断,医生开药,医嘱)\
  140.         values (%ld,'%s','%s','%s','%s');",\
  141.         rec->patientName,rec->time,rec->patientRec,rec->doctorDia,rec->tablet,rec->doctorAdv);
  142.     ret=sqlite3_exec(db,sql,0,0,&errmsg);
  143.     if (ret)
  144.     {
  145.         //sql执行一场
  146.         printf("在添加数据时出现异常:: %s\n",errmsg);
  147.         return EXIT_FAILURE;
  148.     }
  149.     return 0;
  150. }
  151. int callback (myListOP* list,int argc, char ** argv,char** col){
  152.     // for (int i = 0; i < argc; i++)
  153.     // {
  154.     //     /* code */
  155.     // }
  156.     list->append(list,createPatinetRecord(atol(argv[0]),0,argv[1],\
  157.                 argv[2],argv[3],argv[4]));
  158.     return 0;
  159.    
  160. }
  161. int mysqlite3_read(struct patientRecord * rec,myListOP* list){
  162.     char sql[1024]="";
  163.    
  164.     sprintf(sql,"create table if not exists %s (\
  165.         日期 INTEGER ,\
  166.         病人口述 TEXT,\
  167.         医生诊断 TEXT,\
  168.         医生开药 TEXT,\
  169.         医嘱 text \
  170.         );", rec->patientName);
  171.     char ** result;
  172.     char * errmsg;
  173.     int ret = 0;
  174.     ret=sqlite3_exec(db,sql,0,0,&errmsg);
  175.     if (ret)
  176.     {
  177.         //sql执行一场
  178.         printf("在添加表格时出现异常:: %s\n",errmsg);
  179.         return EXIT_FAILURE;
  180.     }
  181.     sprintf(sql,"select * from %s ;", rec->patientName);
  182.     ret=sqlite3_exec(db,sql,callback,list,&errmsg);
  183.     if (ret)
  184.     {
  185.         //sql执行一场
  186.         printf("在添加数据时出现异常:: %s\n",errmsg);
  187.         return EXIT_FAILURE;
  188.     }
  189.     return 0;
  190. }
  191. int serverfun(struct info* info){
  192.     int client = info->fd;
  193.     char ip_human[16]={0};
  194.     int port_human=0;
  195.     struct sockaddr_in client_addr = {0};
  196.     client_addr = info->client_addr;
  197.     inet_ntop(AF_INET,&client_addr.sin_addr,ip_human,16);
  198.     port_human=ntohs(client_addr.sin_port);
  199.     char buf[560] = "";
  200.     int res = read(client,buf,sizeof(unsigned short int));
  201.     int size = *(unsigned short int*)buf;
  202.     if (res == 0)
  203.     {
  204.         printf("客户端已断开连接:\nIP:%s\nport:%d\n",ip_human,port_human);
  205.         close(client);
  206.         fdList->del(fdList,fdList->find(fdList,info,0));
  207.         return 0;
  208.     }
  209.     res = read(client,buf+sizeof(unsigned short int),size-sizeof(unsigned short int));
  210.     myListOP * tmp =0;
  211.     tmp = info->record->unpack(info->record,buf,printRec);
  212.     info->record->destory(info->record);
  213.     info->record=tmp;
  214.     struct send_t * st = 0;
  215.     unsigned int i=0;
  216.     while (st = info->record->slice(info->record,i++))
  217.     {
  218.         if (st->type == send_record)
  219.         {
  220.             mysqlite3_append(&st->patientRecord);
  221.         }
  222.         if (st->type == read_record)
  223.         {
  224.             myListOP* list = myListDInit(printRec);
  225.             mysqlite3_read(&st->patientRecord,list);
  226.             while (list->packed == 0)
  227.             {
  228.                 res = list->pack(list,buf,560,sizeof(struct patientRecord));
  229.                 send(info->fd,buf,res ,0);
  230.             }
  231.             list->destory(list);
  232.         }
  233.         
  234.     }
  235.     return 1;
  236. }
  237. void printEvent(struct epoll_event event){
  238.     printf("fd:%d,ptr:%p-->",event.data.fd,event.data.ptr);
  239. }
  240. int main(int argc, char const *argv[])
  241. {
  242.     if (argc<2)
  243.     {
  244.         printf("请输入端口号\n");
  245.         return 1;
  246.     }
  247.    
  248.     int server = socket(AF_INET,SOCK_STREAM,0);
  249.     sqlite3_open("/home/mr-oy/c-codes/数据库/hospital.db",&db);
  250.     struct sockaddr_in addr={0};
  251.     addr.sin_family=AF_INET;
  252.     addr.sin_port=htons(atoi(argv[1]));
  253.     addr.sin_addr.s_addr=inet_addr("0.0.0.0");
  254.     if(bind(server,(struct sockaddr * )&addr,sizeof(addr))==-1){
  255.         perror("bind:");
  256.         return 1;
  257.     }
  258.     struct sockaddr_in client_addr = {0};
  259.     int client_len = sizeof(client_addr);
  260.     int ret;
  261.     int max = 10;
  262.     listen(server,max);
  263.     char ip_human[16]="";
  264.     int port_human = 0;
  265.     //创建监视列表
  266.     int epoll_handler = epoll_create1(EPOLL_CLOEXEC);
  267.     // 将服务器加入到handeler内
  268.     struct epoll_event serverEvent;
  269.     serverEvent.events=EPOLLIN|EPOLLET;
  270.     serverEvent.data.fd=server;
  271.     epoll_ctl(epoll_handler,EPOLL_CTL_ADD,server,&serverEvent);
  272.     int client;
  273.     fdList = myListDInit((void(*)(void*))printInfo);
  274.     struct info * currentinfo=0;
  275.     struct epoll_event* currentevent=0;
  276.     int* currentfd =0;
  277.     unsigned int i=0;
  278.     // fdList->append(fdList,creatInfo(0,server,&serverEvent));
  279.     myArrayOP* eventList = myArrayInit(20,sizeof(struct epoll_event),printEvent);
  280.     printf("服务器正在运行:\n");
  281.     for (;;)
  282.     {
  283.         i=0;
  284.         memset(eventList->data,0,eventList->max_length*eventList->size);
  285.         eventList->length = epoll_wait(epoll_handler,eventList->data,eventList->max_length,-1);
  286.         while (currentevent = (struct epoll_event*)eventList->slice(eventList,i++))
  287.         {
  288.             currentfd = &(currentevent->data.fd);
  289.             if (*currentfd == server)//有新的客户端连接
  290.             {
  291.                 client = accept(server,(struct sockaddr * )&client_addr,&client_len);
  292.                 struct epoll_event* clientevent = malloc(sizeof(struct epoll_event)) ;
  293.                 memset(clientevent,0,sizeof(struct epoll_event));
  294.                 clientevent->data.fd=client;
  295.                 clientevent->events=EPOLLIN|EPOLLET;
  296.                 fdList->append(fdList,creatInfo(&client_addr,client,clientevent));
  297.                 epoll_ctl(epoll_handler,EPOLL_CTL_ADD,client,clientevent);
  298.                 inet_ntop(AF_INET,&client_addr.sin_addr,ip_human,16);
  299.                 port_human=ntohs(client_addr.sin_port);
  300.                 printf("客户端已连接:\nIP:%s\nport:%d\n",ip_human,port_human);
  301.                 //将该fd添加到epoll
  302.                 continue;;
  303.             }
  304.             //客户端操作
  305.             else if (*currentfd != server)
  306.             {
  307.                 unsigned int index= fdList->findby(fdList,isSameInt,getfd,currentfd,0);
  308.                 // fdList->print(fdList);
  309.                 currentinfo = fdList->slice(fdList,index);
  310.                 serverfun(currentinfo);
  311.             }
  312.             
  313.         }
  314.         
  315.         
  316.         
  317.     }  
  318.     return 0;
  319. }
复制代码
client.c
  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <unistd.h>
  4. #include <stdlib.h>
  5. #include <sys/types.h>
  6. #include <sys/stat.h>
  7. #include <fcntl.h>
  8. #include <pthread.h>
  9. #include <semaphore.h>
  10. #include <wait.h>
  11. #include <signal.h>
  12. #include <sys/socket.h>
  13. #include <arpa/inet.h>
  14. #include <sys/ipc.h>
  15. #include <sys/sem.h>
  16. #include <semaphore.h>
  17. #include <sys/msg.h>
  18. #include <sys/shm.h>
  19. #include <sys/un.h>
  20. #include "doublyList.h
  21. "
  22. #include "array.h
  23. "
  24. struct patientRecord
  25. {
  26.     time_t time;
  27.     char patientName[40];
  28.     char patientRec[128];
  29.     char doctorDia[128];
  30.     char tablet[128];
  31.     char doctorAdv[128];
  32.     //size=4*128+4+40=556
  33. };
  34. enum enum_send_t{
  35.     send_record =1,
  36.     read_record,
  37. };
  38. struct send_t
  39. {
  40.     enum enum_send_t type;
  41.     struct patientRecord patientRecord;
  42. };
  43. struct send_t * createSend_t(enum enum_send_t type,time_t time,char* patientName,\
  44.                         char* patientRec,char* doctorDia,char* tablet,char* doctorAdv){
  45.                            struct send_t * st = malloc (sizeof (struct send_t));
  46.                            st->type = type;
  47.                            struct patientRecord *ret = &st->patientRecord;
  48.                            memset(ret,0,sizeof(struct patientRecord));
  49.                            ret->time = time;
  50.                            strcpy(ret->patientName,patientName);
  51.                            if (patientRec !=0)
  52.                            {
  53.                             strcpy(ret->patientRec,patientRec);
  54.                             strcpy(ret->doctorDia,doctorDia);
  55.                             strcpy(ret->tablet,tablet);
  56.                             strcpy(ret->doctorAdv,doctorAdv);
  57.                            }
  58.                            
  59.                            return st;
  60.                         }
  61. static void printRec(struct patientRecord* rec){
  62.     char timeStr[64]; // 用于存储格式化后的时间字符串
  63.     strftime(timeStr, sizeof(timeStr), "%Y-%m-%d %H:%M:%S", localtime(&rec->time));
  64.     printf("%s::\n 病人描述:%s\n, 医生诊断:%s\n, 开药:%s\n, 医嘱:%s\n",
  65.            timeStr, rec->patientRec, rec->doctorDia, rec->tablet, rec->doctorAdv);
  66. }
  67. static void printSend_t(struct send_t* send){
  68.     if (send->type == send_record)
  69.     {
  70.         printf("send_record\n");
  71.     }
  72.         if (send->type == read_record)
  73.     {
  74.         printf("read_record\n");
  75.     }
  76.     printRec(&send->patientRecord);
  77. }
  78. int main(int argc, char const *argv[])
  79. {
  80.     if (argc<3)
  81.     {
  82.         printf("请输入端口号\n");
  83.         printf("请输入模式\n");
  84.         return 1;
  85.     }
  86.     char patientName[40];
  87.     char patientRec[128];
  88.     char doctorDia[128];
  89.     char tablet[128];
  90.     char doctorAdv[128];
  91.    
  92.     myListOP* list = myListDInit(printSend_t);
  93.     int clinet = socket(AF_INET,SOCK_STREAM,0);
  94.     struct sockaddr_in addr={0};
  95.     addr.sin_family=AF_INET;
  96.     addr.sin_port=htons(atoi(argv[1]));
  97.     addr.sin_addr.s_addr=inet_addr("127.0.0.1");
  98.     char buf[560] = {0};
  99.     int used =0;
  100.     if(connect(clinet,(struct sockaddr*)&addr,sizeof(addr))==-1){
  101.         perror("connect:");
  102.         return 1;
  103.     }
  104.     if (strcmp(argv[2],"-u"))
  105.     {
  106.     for (;;)
  107.     {
  108.         
  109.         printf("请输入病人姓名\n");
  110.         scanf(" %s",patientName);
  111.         printf("请输入病人自述\n");
  112.         scanf(" %s",patientRec);
  113.         printf("请输入医生诊断\n");
  114.         scanf(" %s",doctorDia);
  115.         printf("请输入药物\n");
  116.         scanf(" %s",tablet);
  117.         printf("请输入医嘱\n");
  118.         scanf(" %s",doctorAdv);
  119.         list->append(list,createSend_t(send_record,time(NULL),\
  120.         patientName,patientRec,doctorDia,tablet,doctorAdv
  121.         ));
  122.         used = list->pack(list,buf,560,560);
  123.         write(clinet,buf,used);
  124.     }  
  125.     }
  126.     else{
  127.     for (;;)
  128.     {
  129.         
  130.         printf("请输入病人姓名\n");
  131.         scanf(" %s",patientName);
  132.         list->append(list,createSend_t(read_record,0,\
  133.         patientName,0,0,0,0
  134.         ));
  135.         used = list->pack(list,buf,560,560);
  136.         write(clinet,buf,used);
  137.         while (1)
  138.         {
  139.             used = read(clinet,buf,sizeof(unsigned short int));//理论上会卡死在这行,回头优化
  140.             int size = *(unsigned short int*)buf;
  141.             used = read(clinet,buf+sizeof(unsigned short int),size-sizeof(unsigned short int));
  142.             myListOP * tmp =0;
  143.             tmp = myListDUnpack(0,buf,printRec);
  144.             tmp->print(tmp);
  145.         }
  146.         
  147.         
  148.         
  149.         
  150.     }  
  151.     }
  152.    
  153.    
  154.     return 0;
  155. }
复制代码
依赖:
doublyLIst.c
  1. #include "doublyList.h
  2. "
  3. #include <stdlib.h>
  4. #include <stdio.h>
  5. #include <string.h>
  6. static int isNull(myListOP * self){
  7.     return self==0 || self->data==0;//头的位置是空,则为null
  8. }
  9. static int isEmpty(myListOP * self){
  10.     return self->data->next==0||self->data->data==0;//头的data的指针指向自己则为null
  11. }
  12. static int isNullOrEmpty(myListOP * self){
  13.     return isNull(self)||isEmpty(self);
  14. }
  15. static void* dequeue(myListOP * self){
  16.     void * ret=0;
  17.     if (isNullOrEmpty(self))
  18.     {
  19.         return 0;
  20.     }
  21.     if (self->data->next == self->data) //只有一个的情况下
  22.     {
  23.         self->length--;
  24.         ret = self->data->data;
  25.         self->data->data =0;
  26.         return ret;
  27.     }
  28.    
  29.     myListP head =self->data;
  30.     head->prev->next = head->next;
  31.     head->next->prev=head->prev;
  32.     self->data=head->next;
  33.     ret = head->data;
  34.     self->__head =0; //迭代器重新生成
  35.     self->length--;
  36.     free(head);
  37.     return ret;
  38. }
  39. static void *pop(myListOP * self){
  40.     if (isNullOrEmpty(self))
  41.     {
  42.         return 0;
  43.     }
  44.     void*ret;
  45.     if (self->data->next == self->data) //只有一个的情况下
  46.     {
  47.         self->length--;
  48.         ret = self->data->data;
  49.         self->data->data =0;
  50.         return ret;
  51.     }
  52.     self->length--;
  53.     self->__head=0;//迭代器重新生成
  54.     myListP current=self->data;
  55.     myListP prev=0;
  56.     myListP next=0;
  57.    
  58.     current = current->prev;//定位到尾部
  59.     prev=current->prev;
  60.     next=current->next;
  61.     prev->next=next;
  62.     next->prev=prev;
  63.     ret=current->data;
  64.     current->data=0;
  65.     free(current);
  66.     return ret;
  67. }
  68. static myListP slice (myListOP * self,unsigned int i){
  69.     if (isNullOrEmpty(self)) //判断是否为空
  70.     {
  71.         return 0;
  72.     }
  73.     //期待i在0~.length之间
  74.     //区间分成了三段,0,__index,length,查看i离哪个更近
  75.     unsigned int distanceFromHead = i;
  76.     unsigned int distanceFromTail = self->length - i;
  77.     unsigned int distanceFromCurrent = i - self->__index;
  78.     distanceFromCurrent=distanceFromCurrent>0?distanceFromCurrent:-distanceFromCurrent;
  79.     if (distanceFromHead <= distanceFromTail && distanceFromHead <= distanceFromCurrent)
  80.     {
  81.         //i离头更近,从头开始遍历
  82.         self->__index = 0;
  83.         self->__last = self->data;
  84.         self->__head = self->data;
  85.     }
  86.     else if (distanceFromTail < distanceFromHead && distanceFromTail <= distanceFromCurrent)
  87.     {
  88.         //i离尾更近,从尾开始遍历
  89.         self->__index = self->length - 1;
  90.         self->__last = self->data->prev;
  91.     }
  92.     if (self->__head != self->data)
  93.     {
  94.         self->__index =0;
  95.         self->__last = self->data;
  96.         self->__head=self->data;
  97.     }
  98.     if (i == 0)
  99.     {
  100.         return self->data;
  101.     }
  102.     for ( ; self->__index < i; self->__index++)
  103.     {
  104.         self->__last = self->__last->next;
  105.         if (self->__last == self->__head)
  106.         {
  107.             break;
  108.         }
  109.         
  110.     }
  111.     for (; self->__index > i; self->__index--)
  112.     {
  113.         self->__last = self->__last->prev;
  114.         if (self->__last == self->__head)
  115.         {
  116.             break;
  117.         }
  118.     }
  119.     return self->__last == self->data?0:self->__last;
  120. }
  121. static void* _slice(myListOP * self,unsigned int i){
  122.     // 这里是后实现的,为了避免对内部函数进行重构,未对slice方法进行重命名
  123.     // 实际用户使用的slice应当为_slice
  124.     // 使用的_slice应当为slice
  125.     // 2025/5/9 修复可能的段错误
  126.     myListP obj = slice(self,i);
  127.     return obj?obj->data:obj;
  128. }
  129. static void*del(struct myListOP*self,unsigned int where){
  130.     if (isNullOrEmpty(self))
  131.     {
  132.         return 0;
  133.     }
  134.     if (where == 0)
  135.     {
  136.         return dequeue(self);
  137.     }
  138.     if (where == self->length-1)
  139.     {
  140.         return pop(self);
  141.     }
  142.    
  143.     //存在2个以上的元素
  144.     myListP last=slice(self,where-1);
  145.     myListP current=slice(self,where);
  146.     myListP next=slice(self,where+1);
  147.     void * ret=0;
  148.     last->next=next;
  149.     next->prev=last;
  150.     ret=current->data;
  151.     free(current);
  152.     self->length --;
  153.     self->__head =0;//迭代器重新生成
  154.     return ret;
  155. }
  156. static int _insertHead(struct myListOP*self,void* data){
  157.     if (isNull(self))
  158.     {
  159.         return 0;
  160.     }
  161.     if (self->data->data ==0)
  162.     {
  163.         self->data->data=data;
  164.         self->__head =0;//迭代器
  165.         self->length++;
  166.         return 1;
  167.     }
  168.     myListP current=(myListP) malloc(sizeof(myList));
  169.     current->data=data;
  170.     current->next=self->data;
  171.     current->prev=self->data->prev;
  172.     self->data->prev->next=current;
  173.     self->data->prev=current;
  174.     self->length++;
  175.     // self->data->prev->next=current;
  176.     self->data=current; //迭代器重新生成
  177.     return 1;
  178. }
  179. static int append(struct myListOP*self,void* data){
  180.     if (isNull(self))
  181.     {
  182.         return 0;
  183.     }
  184.     if (self->data->data ==0)
  185.     {
  186.         self->data->data=data;
  187.         self->__head =0;//迭代器
  188.         self->length++;
  189.         return 1;
  190.     }
  191.    
  192.     myListP current=(myListP) malloc(sizeof(myList));
  193.     myListP head = self->data;
  194.     current->data=data;
  195.     current->next=head;
  196.     current->prev=head->prev;
  197.     head->prev->next=current;
  198.     head->prev=current;
  199.     self->__head =0;//迭代器
  200.     self->length++;
  201.     return 1;
  202. }
  203. static int insert(struct myListOP*self,unsigned int where,void* data){
  204.     if (isNull(self))
  205.     {
  206.         return 0;
  207.     }
  208.     if (where ==0 )
  209.     {
  210.         return _insertHead(self,data);
  211.     }
  212.     if (where ==self->length )
  213.     {
  214.         return append(self,data);
  215.     }
  216.    
  217.     myListP last=slice(self,where-1); //最小 where =1
  218.     myListP current=(myListP) malloc(sizeof(myList));
  219.     myListP next=slice(self,where);
  220.     current->data=data;
  221.     current->next=next;
  222.     current->prev=last;
  223.     last->next=current;
  224.     next->prev=current;
  225.     self->__head =0;
  226.     self->length++;
  227.     return 1;
  228. }
  229. static int delAll(struct myListOP*self,unsigned int where){
  230.     void * data = del(self,where);
  231.     if (data)
  232.     {
  233.         free(data);
  234.         return 1;
  235.     }
  236.     return 0;
  237. }
  238. static unsigned int find(struct myListOP*self,void* obj,unsigned int times){
  239.     myListP p =0;
  240.     unsigned int count =0;
  241.     for (unsigned int i = 0; i < -1; i++)
  242.     {
  243.         p=slice(self,i);
  244.         if (p==0)
  245.         {
  246.             break;
  247.         }
  248.         if (p->data==obj)
  249.         {
  250.             if (times == count)
  251.             {
  252.                 return i;
  253.             }
  254.             count ++;
  255.         }
  256.     }
  257.     return -1;
  258. }
  259. static unsigned int findby(struct myListOP*self,int(*cmp)(void*,void*),void*(*filed)(void*),void*target,unsigned int times){//cmp应该返回是否是要找的值
  260.     myListP p =0;
  261.     unsigned int count =0;
  262.     for (unsigned int i = 0; i < -1; i++)
  263.     {
  264.         p=slice(self,i);
  265.         if (p==0)
  266.         {
  267.             break;
  268.         }
  269.         if (cmp(filed(p->data),target)==0)
  270.         {
  271.             if (times == count)
  272.             {
  273.                 return i;
  274.             }
  275.             count ++;
  276.         }
  277.     }
  278.     return -1;
  279. }
  280. static unsigned int unicNoFree (struct myListOP*self,void*(*field)(void*),long unsigned int size,unsigned int times){
  281.     unsigned int count=0;
  282.     unsigned int ret =0;
  283.     for (unsigned int i = 1; i < self->length; i++)
  284.     {
  285.         count =0;
  286.         for (unsigned int j = i+1; j < self->length; j++)
  287.         {
  288.             if (memcmp(field(slice(self,i)->data),field(slice(self,j)->data),size)==0)
  289.             {
  290.                 if (count >= times)
  291.                 {
  292.                     self->delNoFree(self,j);
  293.                     j=j-1;
  294.                 }
  295.                 count=count+1;
  296.                 ret = ret+1;
  297.             }
  298.         }
  299.     }
  300.     return ret;
  301. }
  302. static unsigned int unic (struct myListOP*self,void*(*field)(void*),long unsigned int size,unsigned int times){
  303.     unsigned int count=0;
  304.     unsigned int ret =0;
  305.     for (unsigned int i = 1; i < self->length; i++)
  306.     {
  307.         count =0;
  308.         for (unsigned int j = i+1; j < self->length; j++)
  309.         {
  310.             if (memcmp(field(slice(self,i)->data),field(slice(self,j)->data),size)==0)
  311.             {
  312.                 if (count >= times)
  313.                 {
  314.                     self->del(self,j);
  315.                     j=j-1;
  316.                 }
  317.                 count=count+1;
  318.                 ret = ret+1;
  319.             }
  320.         }
  321.     }
  322.     return ret;
  323. }
  324. static void print(struct myListOP*self){
  325.     // for (unsigned int i = 0; i < self->length; i++)
  326.     // {
  327.     //     self->__str(self->slice(self,i)->data);
  328.     // }
  329.     myListP cur=self->data;
  330.     if (isNullOrEmpty(self))
  331.     {
  332.         return;
  333.     }
  334.     do{
  335.         self->__str(cur->data);
  336.         cur=cur->next;
  337.     }while (cur!=self->data);
  338.    
  339.     printf("\n");
  340. }
  341. static void destory (myListOP *self){
  342.     for (unsigned int i = 0; i < self->length; i++)
  343.     {
  344.         self->del(self,0);
  345.     }
  346.     free(self->data);
  347.     self->data=0;
  348.     free (self);
  349. }
  350. static void destoryNoFree (myListOP *self){
  351.     for (unsigned int i = 0; i < self->length; i++)
  352.     {
  353.         del(self,0);
  354.     }
  355.     // free(self->data);
  356.     self->data=0;
  357.     free (self);
  358. }
  359. static void _quickSort(myListOP *self,long int start,long int end,int(*cmp)(void*, void*),void*(*filed)(void*),int reverse){
  360.     if (start < end) {
  361.         void* base = slice(self, start)->data; // 以要进行排序数组第0个元素为base
  362.         int left = start;  // 左指针
  363.         int right = end;   // 右指针
  364.         while (left < right) {
  365.             // 从右向左找,找到比base小的元素
  366.             while (left < right && (cmp(filed(slice(self, right)->data), filed(base)) * reverse) >= 0) {
  367.                 right--;
  368.             }
  369.             // 比base小,替换left所在位置的元素
  370.             slice(self, left)->data = slice(self, right)->data;
  371.             // 从左向右找,找到比base大的元素
  372.             while (left < right && (cmp(filed(slice(self, left)->data), filed(base)) * reverse) <= 0) {
  373.                 left++;
  374.             }
  375.             // 比base大,替换right所在位置的元素
  376.             slice(self, right)->data = slice(self, left)->data;
  377.         }
  378.         slice(self, left)->data = base; // 将base放到正确的位置
  379.         // 递归排序左右子数组
  380.         _quickSort(self, start, left - 1, cmp,filed ,reverse);
  381.         _quickSort(self, left + 1, end, cmp,filed, reverse);
  382.     }
  383. }
  384. static void quickSort(myListOP *self,int(*cmp)(void*, void*),void*(*filed)(void*),int reverse){
  385.     if (isNullOrEmpty(self))
  386.     {
  387.         return;
  388.     }
  389.     return _quickSort(self,0,self->length-1,cmp,filed,reverse);
  390. }
  391. static unsigned short int mysizeof(char * obj,unsigned short int size,unsigned int i){
  392.     if (obj==0||size==0){return 0;}
  393.     for (; size>1&&*(char*)(obj+size-1) - *(char*)(obj+size-2)==0; size--);//尾地址为obj+size-1
  394.     return size;
  395. }
  396. static unsigned int pack(myListOP *self,char* buf,unsigned int length,unsigned short int max_size){
  397.     return self->packVarLength(self,buf,length,(unsigned short int(*)(void*,unsigned short int ,unsigned int ))mysizeof,max_size);
  398. }
  399. unsigned int packVarLength(myListOP *self,char* buf,unsigned int length,unsigned short (*sizefun)(void* obj,unsigned short int max_size,unsigned int i),unsigned short int max_size){
  400.     //将对象打包成字节流
  401.     unsigned int used=0;
  402.     void* obj=0;
  403.     unsigned short int size=0;
  404.     unsigned short int min_buf_len = sizeof(unsigned short int)*2;
  405.     self->packed=0;
  406.     if (self->pack_use_max_size)
  407.     {
  408.         min_buf_len =  sizeof(unsigned short int)*3;
  409.     }
  410.     if (length<min_buf_len)
  411.     {
  412.         return 0;
  413.     }
  414.     if (isNullOrEmpty(self))
  415.     {
  416.         return 0;
  417.     }
  418.     // 为总大小腾出空间
  419.     used+=sizeof(unsigned short int);
  420.     if (self->pack_use_max_size)
  421.     {
  422.         //如果启用最大大小,则为最大大小腾出空间
  423.         used+=sizeof(unsigned short int);
  424.     }
  425.     //再循环写入每个元素
  426.     while(obj=self->slice(self,self->__lastPacked++)){
  427.         size = sizefun(obj,max_size,self->__lastPacked-1);
  428.         if (self->pack_use_max_size)
  429.         {
  430.             max_size = max_size<size?size:max_size;
  431.         }
  432.         //需要写入的字节数为size+sizeof(unsigned short int)
  433.         //如果写入量超过长度,则返回实际使用量;
  434.         if (used+size+sizeof(unsigned short int)>length)
  435.         {
  436.             *(unsigned short int *)(buf) =used;
  437.             if (self->pack_use_max_size)
  438.             {
  439.                 *(unsigned short int *)(buf+sizeof(unsigned short int)) =max_size;
  440.             }
  441.             self->__lastPacked--;//回退计数器
  442.             return used;//未打包完,返回使用量
  443.         }
  444.         //否则则写入大小和数据
  445.         *(unsigned short int *)(buf+used) =size;
  446.         used+=sizeof(unsigned short int);
  447.         memcpy(buf+used,obj,size);
  448.         used+=size;
  449.     }
  450.     self->__lastPacked = 0;//这里说明打包完了
  451.     *(unsigned short int *)(buf) =used;
  452.     if (self->pack_use_max_size)
  453.     {
  454.         *(unsigned short int *)(buf+sizeof(unsigned short int)) =max_size;
  455.     }
  456.     self->packed=1;
  457.     return used;
  458. }
  459. myListOP* myListDUnpack(char pack_use_max_size,char* buf,void(*printData)(void*)){
  460.     unsigned int total = *(unsigned short int *)buf;//协议包的总大小
  461.     if (total<2*sizeof(unsigned short int)+1)//如果比最小的情况还小(一个总大小,一个对象,对象只写入了一个字节)
  462.     {
  463.         return 0;
  464.     }
  465.    
  466.     unsigned int delta=sizeof(unsigned short int);//偏移量,头两个字节是协议包大小
  467.     unsigned int num =0;//总元素数量
  468.     unsigned int maxSize = *(unsigned short int *)(buf+delta);//最大元素的大小,假设第一个最大
  469.     unsigned int currentSize=0;
  470.     //找到要申请的地址的大小
  471.     if (pack_use_max_size)
  472.     {
  473.         maxSize = *(unsigned short int *)(buf+sizeof(unsigned short int));
  474.         delta+=sizeof(unsigned short int);
  475.     }
  476.     // 先获取最大的大小
  477.     while (delta<total)//不会出现等于,最少会写入1字节的obj
  478.     {
  479.         num=num+1;
  480.         currentSize = *(unsigned short int *)(buf+delta);
  481.         if (maxSize<currentSize)
  482.         {
  483.             maxSize = currentSize;
  484.         }
  485.         delta+=currentSize+sizeof(unsigned short int);
  486.     }
  487.    
  488.     delta = sizeof(unsigned short int);
  489.     if (pack_use_max_size)
  490.     {
  491.         delta+=sizeof(unsigned short int);
  492.     }
  493.     //再申请内存
  494.     myListOP* arr = myListDInit(printData);if (arr == 0){return 0;}
  495.     arr->pack_use_max_size=pack_use_max_size;//继承原有的格式
  496.     while (delta<total)//不会出现等于,最少会写入1字节的obj
  497.     {
  498.         void* obj=malloc(maxSize);if (obj == 0){return 0;}
  499.         currentSize = *(unsigned short int *)(buf+delta);
  500.         delta+=sizeof(unsigned short int);
  501.         memset(obj,*(char*)(buf+delta+currentSize-1),maxSize);//以最后一个字节初始化
  502.         memcpy(obj,buf+delta,currentSize);
  503.         delta+=currentSize;
  504.         arr->append(arr,obj);//对链表,存的是对象的地址
  505.     }
  506.     return arr;
  507. }
  508. static myListOP* unpack(myListOP* self,char* buf,void(*printData)(void*)){
  509.     //兼容层
  510.     return myListDUnpack(self->pack_use_max_size,buf,printData);
  511. }
  512. static int delByAddrNoFree(myListOP *self,void* obj,unsigned int times){
  513.     if (self==0||self->isNullOrEmpty(self)||obj==0)
  514.     {
  515.         return 0;
  516.     }
  517.     do
  518.     {
  519.         unsigned int where = self->find(self,obj,times);
  520.         if (where == -1)
  521.         {
  522.             break;
  523.         }
  524.         self->delNoFree(self,where);
  525.     } while (times--);
  526.     return times;   
  527. }
  528. static int delByAddr(myListOP *self,void* obj,unsigned int times){
  529.     if (self==0||self->isNullOrEmpty(self)||obj==0)
  530.     {
  531.         return 0;
  532.     }
  533.     do
  534.     {
  535.         unsigned int where = self->find(self,obj,times);
  536.         if (where == -1)
  537.         {
  538.             break;
  539.         }
  540.         self->del(self,where);
  541.     } while (times--);
  542.     return times;   
  543. }
  544. static int add(myListOP *self,myListOP *other){
  545.     void* obj =0;
  546.     unsigned int i =0;
  547.     while (obj=other->slice(other,i++))
  548.     {
  549.         self->append(self,obj);
  550.     }
  551. }
  552. static int sub(myListOP *self,myListOP *other){
  553.     int ret =0;
  554.     if (self ==0||other ==0)
  555.     {
  556.         return ret;
  557.     }
  558.     if (self->isNullOrEmpty(self)||other->isNullOrEmpty(other))
  559.     {
  560.         return ret;
  561.     }
  562.     void* obj_self =0;
  563.     void* obj_other=0;
  564.     unsigned int i =0;
  565.     unsigned int j=0;
  566.    
  567.     while (obj_other=other->slice(other,i++))
  568.     {
  569.         while (obj_self=self->slice(self,j++))
  570.         {
  571.             if (obj_other==obj_self)
  572.             {
  573.                 self->delByAddr(self,obj_self,0);
  574.             }
  575.         }
  576.     }
  577. }
  578. myListOP* myListDInit(void(*printData)(void*)){
  579.     myListOP *self = (myListOP *) malloc(sizeof(myListOP));
  580.     if (self ==0)
  581.     {
  582.         return 0;
  583.     }
  584.     bzero(self,sizeof(myListOP));
  585.     //申请头节点
  586.     self->data = (myListP) malloc(sizeof(myList));
  587.     if (self->data ==0)
  588.     {
  589.         return 0;
  590.     }
  591.     self->data->data=0;
  592.     self->data->next=self->data;
  593.     self->data->prev=self->data;
  594.     self->append=append;
  595.     self->del=delAll;
  596.     self->delNoFree = del;
  597.     self->__str=printData;
  598.     self->destory=destory;
  599.     self->find=find;
  600.     self->findby=findby;
  601.     self->insert=insert;
  602.     self->isNullOrEmpty=isNullOrEmpty;
  603.     self->length=0;
  604.     self->slice=_slice;
  605.     self->_slice=slice;
  606.     self->unic=unic;
  607.     self->print=print;
  608.     self->dequeue=dequeue;
  609.     self->pop=pop;
  610.     self->push=(int (*)(struct myListOP*,void* data))append;
  611.     self->queue=(int (*)(struct myListOP*,void* data))append;
  612.     self->quickSort=quickSort;
  613.     self->_quickSort=_quickSort;
  614.     self->destoryNoFree=destoryNoFree;
  615.     self->unicNoFree=unicNoFree;
  616.     self->packVarLength=packVarLength;
  617.     self->pack=pack;
  618.     self->unpack=unpack;
  619.     self->delByAddr = delByAddr;
  620.     return self;
  621. }
  622.    
复制代码
  1. doublyList.h
复制代码
  1. #ifndef  __MYDOUBLYLIST_STRUCT__
  2. #define __MYDOUBLYLIST_STRUCT__
  3. /* 双向循环链表,涵盖操作类
  4. *  
  5. * 用法: 需要外部创建结构体或对象,同时准备好该结构体或对象的打印(print)方法
  6. * 请注意:长度从0开始,到length结束
  7. * 推荐以以下方式迭代链表
  8. * while(obj=.slice(,i++))
  9. * 以下划线(_)开头的方法为某一方法的补充,或是低级实现,理想情况下不应当被使用
  10. * 以下划线(__)开头的字段为内部实现依赖的字段,不应当被外界改变
  11. * 在数组的实现中,部分方法依赖于长度(.length),其长度不应当被改变
  12. * 以下操作是合法的
  13. * _slice(0),_slice(length),_slice(-1),_slice(length+1)返回值分别为头数据,尾数据,0,0
  14. * slice(1),slice(length),返回值分别为头尾节点内存的对象.
  15. * 同一个链表操作类操作不同的链表 即op1->fun(op2,agrs) 该结果应该与 op2->fun(op2,agrs) 一致,但无法保证跨链表操作类结果一致
  16. * 如需排序/去重/按字段查找,则需准备字段的方法
  17. * 如需排序,需要提供比较方法
  18. *
  19. * 初始 myListOP* mylistOP =  myListDInit((void(*)(void*))printData);
  20. * 2025/5/9  修改返回void* 的slice可能段错误的问题
  21. * 2025/5/10 修补编译器提示,增加unicNoFree,增加pack与unpack
  22. * 2025/5/11 补充测试函数,放弃对单向链表的支持,重命名新增NoFree函数
  23. */
  24. typedef struct myList{
  25. void * data;
  26. struct myList * prev;
  27. struct myList * next;
  28. }myList,* myListP;
  29. typedef struct myListOP{
  30. myListP data;
  31. //判断链是否为空,空返回1,非空返回0
  32. int (*isNullOrEmpty)(struct myListOP*);
  33. //将obj存放入链表的尾部,成功返回1,失败返回0
  34. int (*append)(struct myListOP*,void* data);
  35. /*
  36. 删除链表上的第where个节点,会自动free该节点指向的对象
  37. returnVal: 0失败,1成功
  38. */
  39. int (*del)(struct myListOP*,unsigned int where);
  40. /*
  41. 删除链表上的第where个节点,会自动free该节点指向的对象
  42. returnVal: 该节点指向的对象的地址
  43. */
  44. void* (*delNoFree)(struct myListOP*,unsigned int where);
  45. /*
  46. 在where处插入obj对象
  47. returnVal: 0失败,1成功
  48. */
  49. int (*insert)(struct myListOP*,unsigned int where,void* obj);
  50. /*
  51. 查找该对象times+1次,返回times+1次所对应的下标,times为0表示取第一个
  52. returnVal: where,-1表示未找到该对象
  53. */
  54. unsigned int (*find)(struct myListOP*self,void* obj,unsigned int times);
  55. /*
  56. 在链表上保证链表上某个对象最多不出现time+1次,会free对象
  57. field:取字段函数,接受链表内存储的对象,返回要排序的字段的地址
  58. size:该字段的大小
  59. 具体调用:memcmp(field(slice(self,i)->data),field(slice(self,j)->data),size)==0
  60. returnVal:删除了几个对象
  61. */
  62. unsigned int (*unic)(struct myListOP*self,void*(*field)(void*),long unsigned int size,unsigned int times);
  63.      /*
  64. 在链表上保证链表上某个对象最多不出现time+1次,不会free对象
  65. field:取字段函数,接受链表内存储的对象,返回要排序的字段的地址
  66. size:该字段的大小
  67. 具体调用:memcmp(field(slice(self,i)->data),field(slice(self,j)->data),size)==0
  68. returnVal:删除了几个对象
  69. */
  70. unsigned int (*unicNoFree)(struct myListOP*self,void*(*field)(void*),long unsigned int size,unsigned int times);
  71. /*
  72. 返回链表内第i个链的地址,不应当被外部调用
  73. */
  74. myList* (*_slice)(struct myListOP* self,unsigned int i);
  75. /*
  76. 返回链表内第i个对象的地址
  77. 应该被这么用:
  78. while(obj=op->slice(op,i++)){
  79. do something to op
  80. }
  81. */
  82. void* (*slice)(struct myListOP* self,unsigned int i);
  83. // 销毁链表,并且销毁链表内的所有对象(free obj)
  84. void (*destory)(struct myListOP *self);
  85. // 将链表内的所有对象挨个传给.__str方法,.__str方法应当在初始化时被正确设置为接受对象的地址并进行输出
  86. void (*print)(struct myListOP * self);
  87. /*
  88. field:取字段函数,接受链表内存储的对象,返回要排序的字段的地址
  89. cmp: 比较函数,接收target,接受由field产生的字段的地址,返回两个值的差值(cmp(filed(p->data),target))
  90. target:要比较的值的地址
  91. times:找第times+1个
  92. returnVal:找到返回where,没找到返回-1
  93. */
  94. unsigned int (*findby)(struct myListOP*self,int(*cmp)(void*,void*),void*(*field)(void*),void*target,unsigned int times);
  95. //.print会调用这个方法输出链表内的对象(会将每一个对象的地址输入进这个方法)
  96. void (*__str)(void*);
  97. //删除链表的第一个节点,将其内部存放的对象的地址返回(而不是free)
  98. void*  (*dequeue)(struct myListOP* self);
  99. //删除链表的尾节点,将其内部存放的对象的地址返回(而不是free)
  100. void*  (*pop)(struct myListOP* self);
  101. //将obj存放入链表的尾部,成功返回1,失败返回0
  102. int  (*push)(struct myListOP*,void* obj);
  103. //将obj存放入链表的尾部,成功返回1,失败返回0
  104. int  (*queue)(struct myListOP*,void* data);
  105. //对链表的一部分进行快速排序
  106. void (*_quickSort)(struct myListOP*self,long int start,long int end,int(*cmp)(void*, void*),void*(*filed)(void*),int reverse);
  107. //对整个链表快速排序,field:根据对象的哪个字段地址进行排序,cmp接受两个字段的地址,返回两个字段值的差值,reverse为正则正序,为负则倒叙,0不排序
  108. void (*quickSort)(struct myListOP *self,int(*cmp)(void*, void*),void*(*filed)(void*),int reverse);
  109. //删除整个链表,但不释放链表中的对象
  110. void (*destoryNoFree)(struct myListOP*self);
  111. //按地址删除某一元素,obj要删除的对象,times删除次数,返回实际删除了几次,不释放obj
  112. int (*delByAddr)(struct myListOP *self,void* obj,unsigned int times);
  113. /*
  114. 将对象打包成字节流,写入到buf,会删除重复的尾字节
  115. 字节流格式:unsigened short int used(2字节) unsigened short int datalen(2字节) data
  116. 如果.pack_use_max_size != 0,则在used 之后写入该对象的最大大小
  117. buf:缓冲区,字节流写入的地址
  118. length:缓冲区buf的长度
  119. max_size:链表上存储的obj最大的大小(如大小不一致,请使用.packVarLength)
  120. returnVal:往缓冲区实际写入的字节数
  121. */
  122. unsigned int (*pack)(struct myListOP *self,char* buf,unsigned int length,unsigned short int max_size);
  123. /*
  124. 将对象打包成字节流,写入到buf,会删除重复的尾字节
  125. 字节流格式:unsigened short int used(2字节)unsigened short int datalen(2字节) data
  126. 如果.pack_use_max_size != 0,则在used 之后写入该对象的最大大小
  127. buf:缓冲区,字节流写入的地址
  128. length:缓冲区buf的长度
  129. size:取size函数,传入obj对象,返回这个对象占用了多少个字节,obj list里存放的对象,max_size:这个对象理应占的最大字节数,i,第i个对象
  130. 如果size函数返回了一个比max_size更大的数,那么以size返回的数据的最大值作为max_size被写入
  131. returnVal:往缓冲区实际写入的字节数
  132. */
  133. unsigned int (*packVarLength)(struct myListOP *self,char* buf,unsigned int length,unsigned short (*size)(void* obj,unsigned short int max_size,unsigned int i),unsigned short int max_size);
  134. /*
  135. 将字节流解包成对象,会写入尾部的重复字节
  136. 字节流格式:unsigened short int used(2字节)unsigened short int datalen(2字节) data
  137. 如果.pack_use_max_size != 0,使用used之后的2字节作为最大长度进行创建内存
  138. buf:缓冲区,字节流读取的地址
  139. printData:返回操作类初始化时需要的printData
  140. returnVal:操作类
  141. */
  142. struct myListOP* (*unpack)(struct myListOP* self,char* buf,void(*printData)(void*));
  143. unsigned int length;//链表的长度
  144. unsigned int __index;//内部变量,加速slice与_slice的返回
  145. unsigned int __lastPacked;//内部变量,记录上次打包的位置
  146. char pack_use_max_size;//是否使用最大的元素大小,修改打包的格式
  147. char packed;//是否打包完毕
  148. myListP __last;//内部变量,加速slice与_slice的返回
  149. myListP __head;//内部变量,加速slice与_slice的返回
  150. } myListOP;
  151. //初始化函数
  152. myListOP* myListDInit(void(*printData)(void*));
  153. /*
  154. 将字节流解包成对象,会写入尾部的重复字节
  155. 字节流格式:unsigened short int used(2字节)unsigened short int datalen(2字节) data
  156. 如果pack_use_max_size != 0,使用used之后的2字节作为最大长度进行创建内存
  157. buf:缓冲区,字节流读取的地址
  158. printData:返回操作类初始化时需要的printData
  159. returnVal:操作类
  160. */
  161. myListOP* myListDUnpack(char pack_use_max_size,char* buf,void(*printData)(void*));
  162. #endif
复制代码
  1. array.c
复制代码
  1. // 实现list的头插,尾插,头删,尾删,任意位置删除,任意位置添加
  2. #include <stdio.h>
  3. #include <string.h>
  4. #include "array.h
  5. "
  6. static int isNull(myArrayOP* self){
  7. if (self ==0 || self->data ==0){return 1;}
  8. return 0;
  9. }
  10. static int isNullOrEmpty(myArrayOP* self){
  11. if (isNull(self) || self->length ==0)
  12. {
  13.      return 1;
  14. }
  15. return 0;
  16. }
  17. static void* slice(myArrayOP* self,unsigned int i){
  18. if (i>= self->length || i<0)
  19. {
  20.      return 0;
  21. }
  22. return self->data+self->size*i;
  23. }
  24. static int del(myArrayOP* self,unsigned int where){
  25. if (isNullOrEmpty(self))
  26. {
  27.      return 0;
  28. }//判断是否非空
  29. void* data = self->data;
  30. if (where > self->length || where <0)
  31. {
  32.      return 0;
  33. }
  34. if (self->length == where+1)//如果最后一个,则直接移动length,避免越界
  35. {
  36.      self->length = self->length-1;
  37.      return 0;
  38. }
  39. for (unsigned int i = where; i < self->length; i++)
  40. {
  41.      // data->data[i] = data->data[i+1];
  42.      memcpy(data+self->size*i,data+self->size*(i+1),self->size);
  43. }
  44. self->length = self->length-1;
  45. return 0;
  46. }
  47. static void* delNoFree (myArrayOP* self,unsigned int where){
  48. if (isNullOrEmpty(self))
  49. {
  50.      return 0;
  51. }//判断是否非空
  52. void* ret = malloc(self->size);
  53. memcpy(ret,self->slice(self,where),self->size);
  54. del(self,where);
  55. return ret;
  56. }
  57. static int insert(myArrayOP* self,unsigned int where,void* obj){
  58. if (isNull(self))
  59. {
  60.      return 0;
  61. }//判断是否非空
  62. void* data = self->data;
  63. if (self->length == self->max_length)
  64. {
  65.      return 0;
  66. }
  67. if (where > self->length||where<0)
  68. {
  69.      return 0;
  70. }
  71. if (self->length ==0)
  72. {
  73.      // data->data[0] = obj;
  74.      memcpy(data,obj,self->size);
  75.      self->length++;
  76.      return 1;
  77. }
  78. for (unsigned int i =self->length ; i > where; i--)
  79. {
  80.      memcpy(data+self->size*i,data+self->size*(i-1),self->size);
  81. }
  82. self->length = self->length+1;
  83. memcpy(data+where*self->size,obj,self->size);
  84. return 1;
  85. }
  86. static int insertHead(myArrayOP* self,void* num){
  87. return insert(self,0,num);
  88. }
  89. static int insertTail(myArrayOP* self,void* num){
  90. if (isNull(self))
  91. {
  92.      return 0;
  93. }//判断是否非空
  94. return insert(self,self->length,num);
  95. }
  96. static int delHead (myArrayOP* self){
  97. return del(self,0);
  98. }
  99. static int delTail (myArrayOP* self){
  100. return del(self,self->length);
  101. }
  102. static void* delHeadNoFree (myArrayOP* self){
  103. return delNoFree(self,0);
  104. }
  105. static void* delTailNoFree (myArrayOP* self){
  106. return delNoFree(self,self->length-1);
  107. }
  108. static unsigned int find(struct myArrayOP*self,void* obj,unsigned int times){
  109. void* p =0;
  110. unsigned int count =0;
  111. for (unsigned int i = 0; i < -1; i++)
  112. {
  113.      p=slice(self,i);
  114.      if (p==0)
  115.      {
  116.          break;
  117.      }
  118.      if (p==obj)
  119.      {
  120.          if (times == count)
  121.          {
  122.              return i;
  123.          }
  124.          count ++;
  125.      }
  126. }
  127. return -1;
  128. }
  129. static unsigned int findby(struct myArrayOP*self,int(*cmp)(void*,void*),void*(*filed)(void*),void*target,unsigned int times){//cmp应该返回是否是要找的值
  130. void* p =0;
  131. unsigned int count =0;
  132. for (unsigned int i = 0; i < -1; i++)
  133. {
  134.      p=self->slice(self,i);
  135.      if (p==0)
  136.      {
  137.          break;
  138.      }
  139.      if (cmp(filed(p),target)==0)
  140.      {
  141.          if (times == count)
  142.          {
  143.              return i;
  144.          }
  145.          count ++;
  146.      }
  147. }
  148. return -1;
  149. }
  150. static unsigned int _index(myArrayOP* self,void* obj){
  151. return find(self, obj,0);
  152. }
  153. static unsigned int unic (struct myArrayOP*self,void*(*field)(void*),unsigned int times){
  154. unsigned int count=0;
  155. unsigned int ret =0;
  156. for (unsigned int i = 1; i < self->length; i++)
  157. {
  158.      count =0;
  159.      for (unsigned int j = i+1; j < self->length; j++)
  160.      {
  161.          if (memcmp(field(self->slice(self,i)),field(self->slice(self,j)),self->size)==0)
  162.          {
  163.              if (count >= times)
  164.              {
  165.                  self->del(self,j);
  166.                  j=j-1;
  167.              }
  168.              count=count+1;
  169.              ret = ret+1;
  170.          }
  171.      }
  172. }
  173. return ret;
  174. }
  175. static void print(myArrayOP * self){
  176. void* obj;
  177. unsigned int i=0;
  178. if (isNullOrEmpty(self))
  179. {
  180.      return;
  181. }
  182. while (obj=self->slice(self,i++))
  183. {
  184.      self->__str(obj);
  185. }
  186. printf("\n");
  187. return;
  188. }
  189. static void destory(myArrayOP *self){
  190. if (self ==0)
  191. {
  192.      return;
  193. }
  194. if (self->data ==0)
  195. {
  196.      return;
  197. }
  198. free (self->data);
  199. self->data=0;
  200. free(self);
  201. }
  202. static void _quickSort(myArrayOP *self,long int start,long int end,int(*cmp)(void*, void*),void*(*filed)(void*),int reverse){
  203. if (start < end) {
  204.      void* base = malloc(self->size);
  205.      memcpy(base,slice(self, start),self->size);// 以要进行排序数组第0个元素为base
  206.      int left = start;  // 左指针
  207.      int right = end;   // 右指针
  208.      while (left < right) {
  209.          // 从右向左找,找到比base小的元素
  210.          while (left < right && (cmp(filed(slice(self, right)), filed(base)) * reverse) >= 0) {
  211.              right--;
  212.          }
  213.          memcpy(slice(self, left),slice(self, right),self->size);
  214.          while (left < right && (cmp(filed(slice(self, left)), filed(base)) * reverse) <= 0) {
  215.              left++;
  216.          }
  217.          memcpy(slice(self, right),slice(self, left),self->size);
  218.      }
  219.      // slice(self, left)->data = base; // 将base放到正确的位置
  220.      memcpy(slice(self, left),base,self->size);
  221.      free(base);
  222.      // 递归排序左右子数组
  223.      _quickSort(self, start, left - 1, cmp,filed, reverse);
  224.      _quickSort(self, left + 1, end, cmp,filed, reverse);
  225. }
  226. }
  227. static void quickSort(myArrayOP *self,int(*cmp)(void*, void*),void*(*filed)(void*),int reverse){
  228. if (isNullOrEmpty(self))
  229. {
  230.      return;
  231. }
  232. return _quickSort(self,0,self->length-1,cmp,filed,reverse);
  233. }
  234. static unsigned short int mysizeof(char * obj,unsigned int size){
  235. if (obj==0||size==0){return 0;}
  236. for (; size>1&&*(char*)(obj+size-1) - *(char*)(obj+size-2)==0; size--);//尾地址为obj+size-1
  237. return size;
  238. }
  239. static unsigned int pack(myArrayOP *self,char* buf,unsigned int length){
  240. //将对象打包成字节流
  241. //格式:unsigened short int used(2字节)unsigened short int len(2字节)data
  242. //如果定义了宏 __PACK_WRITE_MAXSIZE__,则在used后写入max_size
  243. unsigned int used=0;
  244. void* obj=0;
  245. unsigned short int size=0;
  246. unsigned int min_buf_len = sizeof(unsigned short int)*2;
  247. self->packed=0;
  248. if (self->pack_use_max_size)
  249. {
  250.      min_buf_len =  sizeof(unsigned short int)*3;
  251. }
  252. if (length<min_buf_len)
  253. {
  254.      return 0;
  255. }
  256. if (isNullOrEmpty(self))
  257. {
  258.      return 0;
  259. }
  260. // 为总大小腾出空间
  261. used+=sizeof(unsigned short int);
  262. if (self->pack_use_max_size)
  263. {
  264.      *(unsigned short int *)(buf+used) =self->size;
  265.      used+=sizeof(unsigned short int);
  266. }
  267. //再循环写入每个元素
  268. while(obj=self->slice(self,self->__lastPacked++)){
  269.      size = mysizeof(obj,self->size);
  270.      //需要写入的字节数为size+sizeof(unsigned short int)
  271.      //如果写入量超过长度,则返回实际使用量;
  272.      if (used+size+sizeof(unsigned short int)>length)
  273.      {
  274.              *(unsigned short int *)(buf) =used;
  275.              self->__lastPacked--;//回退计数器
  276.              return used;//未打包完,返回使用量
  277.      }
  278.      //否则则写入大小和数据
  279.      *(unsigned short int *)(buf+used) =size;
  280.      used+=sizeof(unsigned short int);
  281.      memcpy(buf+used,obj,size);
  282.      used+=size;
  283. }
  284. self->__lastPacked = 0;//这里说明打包完了
  285. self->packed=1;
  286. *(unsigned short int *)(buf) =used;
  287. return used;
  288. }
  289. myArrayOP* myArrayUnpack(char pack_use_max_size,char* buf,void(*printData)(void*)){
  290. unsigned int total = *(unsigned short int *)buf;//协议包的总大小
  291. if (total<2*sizeof(unsigned short int)+1)//如果比最小的情况还小(一个总大小,一个对象,对象只写入了一个字节)
  292. {
  293.      return 0;
  294. }
  295. //先循环遍历,找到最大的元素大小和要申请的地址的大小
  296. unsigned int delta=sizeof(unsigned short int);//偏移量,头两个字节是协议包大小
  297. unsigned int num =0;//总元素数量
  298. unsigned int maxSize = *(unsigned short int *)(buf+delta);//最大元素的大小,假设第一个最大
  299. unsigned int currentSize=0;
  300. if (pack_use_max_size)
  301. {
  302.      // 如果有写max_size 则使用
  303.      maxSize = *(unsigned short int *)(buf+sizeof(unsigned short int));
  304.      delta+=sizeof(unsigned short int);
  305. }
  306.      while (delta<total)//不会出现等于,最少会写入1字节的obj
  307. {
  308.      num=num+1;
  309.      currentSize = *(unsigned short int *)(buf+delta);
  310.      if (maxSize<currentSize)
  311.      {
  312.          maxSize = currentSize;
  313.      }
  314.      delta+=currentSize+sizeof(unsigned short int);
  315. }
  316. delta = sizeof(unsigned short int);
  317. //再申请内存
  318. myArrayOP* arr = myArrayInit(maxSize*num,maxSize,printData);if (arr == 0){return 0;}
  319. //为了方便还原数据,申请maxSize大小的内存;
  320. void* obj=malloc(maxSize);if (obj == 0){return 0;}
  321. while (delta<total)//不会出现等于,最少会写入1字节的obj
  322. {
  323.      currentSize = *(unsigned short int *)(buf+delta);
  324.      delta+=sizeof(unsigned short int);
  325.      memset(obj,*(char*)(buf+delta+currentSize-1),maxSize);//以最后一个字节初始化
  326.      memcpy(obj,buf+delta,currentSize);
  327.      delta+=currentSize;
  328.      arr->append(arr,obj);
  329. }
  330. free(obj);
  331. arr->pack_use_max_size=pack_use_max_size;//继承原有的格式
  332. return arr;
  333. }
  334. static myArrayOP* unpack(myArrayOP* self,char* buf,void(*printData)(void*)){
  335. //兼容层
  336. return myArrayUnpack(self->pack_use_max_size,buf,printData);
  337. }
  338. static int delByAddr(myArrayOP *self,void* obj){
  339. if (self==0)
  340. {
  341.      return -1;
  342. }
  343. if (isNullOrEmpty(self))
  344. {
  345.      return -1;
  346. }
  347. if (obj<self->data||obj>(self->data+self->length*self->size))
  348. {
  349.      return -1;
  350. }
  351. unsigned int where = (unsigned int)((char*)obj - (char*)self->data)/self->size;
  352. self->del(self,where);
  353. return where;
  354. }
  355. static int add(myArrayOP *self,myArrayOP *other){
  356. void* obj =0;
  357. unsigned int i =0;
  358. while (obj=other->slice(other,i++))
  359. {
  360.      self->append(self,obj);
  361. }
  362. }
  363. static int sub(myArrayOP *self,myArrayOP *other){
  364. int ret =0;
  365. if (self ==0||other ==0)
  366. {
  367.      return ret;
  368. }
  369. if (self->isNullOrEmpty(self)||other->isNullOrEmpty(other))
  370. {
  371.      return ret;
  372. }
  373. if (self->size!=other->size) //两个数组中数据大小不一样,不比较
  374. {
  375.      ret = -1;
  376.      return ret;
  377. }
  378. unsigned int size = self->size;
  379. void* obj_self =0;
  380. void* obj_other=0;
  381. unsigned int i =0;
  382. unsigned int j=0;
  383. while (obj_other=other->slice(other,i++))
  384. {
  385.      while (obj_self=self->slice(self,j++))
  386.      {
  387.          if (memcmp(obj_self,obj_other,size)==0)
  388.          {
  389.              self->delByAddr(self,obj_self);
  390.          }
  391.      }
  392. }
  393. }
  394. static myArrayOP* copy(myArrayOP* self){
  395. myArrayOP* ret = myArrayInit(self->max_length,self->size,self->__str);
  396. memcpy(ret->data,self->data,self->size*self->length);
  397. return  ret;
  398. }
  399. static myArrayOP* setter(myArrayOP* self,myArrayOP*other){
  400. memcpy(self->data,other->data,self->size*self->length);
  401. return  self;
  402. }
  403. myArrayOP* myArrayInit(unsigned int max_length,unsigned int size,void(*printData)(void*)){
  404. myArrayOP * self = 0;
  405. self = (myArrayOP*) malloc(sizeof(myArrayOP));
  406. bzero(self,sizeof(myArrayOP));
  407. self->data = calloc(max_length,size);
  408. // malloc(sizeof(myList));
  409. bzero(self->data,sizeof(max_length*size));
  410. self->max_length=max_length;
  411. self->size=size;
  412. self->__str=printData;
  413. self->del = del;
  414. self->delHead=delHead;
  415. self->delTail=delTail;
  416. self->delNoFree=delNoFree;
  417. self->find=find;
  418. self->index=_index;
  419. self->insert=insert;
  420. self->inserTail=insertTail;
  421. self->insertHead=insertHead;
  422. self->isNullOrEmpty=isNullOrEmpty;
  423. self->slice=slice;
  424. self->unic=unic;
  425. self->print=print;
  426. self->destory=destory;
  427. self->delHeadNoFree=delHeadNoFree;
  428. self->delTailNoFree=delTailNoFree;
  429. self->delNoFree=delNoFree;
  430. self->quickSort=quickSort;
  431. self->_quickSort=_quickSort;
  432. self->append=insertTail;
  433. self->push=insertTail;
  434. self->queue=insertTail;
  435. self->dequeue=delHeadNoFree;
  436. self->pop=delTailNoFree;
  437. self->findby=findby;
  438. self->pack=pack;
  439. self->unpack=unpack;
  440. self->copy=copy;
  441. self->setter = setter;
  442. return self;
  443. }
复制代码
  1. array.h
复制代码
  1. #ifndef  __MYARRAYLIST_STRUCT__
  2. #define __MYARRAYLIST_STRUCT__
  3. #include <stdlib.h>
  4. // 数组,堆上的对象数组
  5. // 用法: 需要外部创建结构体或对象,同时准备好该结构体或对象的打印(print)方法
  6. // 请注意:长度从0开始,到length结束
  7. // 推荐以以下方式迭代链表
  8. // while(obj=.slice(,i++))
  9. // 以下划线(_)开头的方法为某一方法的补充,或是低级实现,理想情况下不应当被使用
  10. // 以下划线(__)开头的字段为内部实现依赖的字段,不应当被外界改变
  11. // 在数组的实现中,部分方法依赖于长度(.length),其长度不应当被改变
  12. // 以下操作是合法的
  13. // _slice(0),_slice(length),_slice(-1),_slice(length+1)返回值分别为头数据,尾数据,0,0
  14. // slice(1),slice(length),返回值分别为头尾节点内存的对象.
  15. // 同一个链表操作类操作不同的链表 即op1->fun(op2,agrs) 该结果应该与 op2->fun(op2,agrs) 一致,但无法保证跨链表操作类结果一致
  16. /* 封装测试于2025/4/30,修复部分.length操作
  17. *  
  18. * 2025/4/16 添加类
  19. * 2025/4/16 添加通用的测试方法
  20. * 2025/4/25 添加_destory方法,未测试,理应是好的
  21. * 2025/4/27 修复findby与quickSort,_quickSort,findby的cmp函数,使其统一,并新增字段field函数,应当返回一对象内部的地址
  22. * 2025/4/27 针对有头单项链表测试,修改有头单项链表,定义1-.length为合法操作
  23. * 2025/5/9  修补数组,使其对任意的obj有效,重命名新增NoFree函数
  24. * 2025/5/10 新增pack和unpack方法,打包/解包成数据流
  25. */
  26. typedef struct myArrayOP{
  27. void* data;  //堆上的数组
  28. size_t length; //目前的长度,0为空
  29. size_t max_length;//数组的最大长度
  30. unsigned int __lastPacked;
  31. char pack_use_max_size;//是否使用最大的元素大小
  32. char packed;
  33. void (*__str)(void*);//打印方法
  34. unsigned short int size;//内部每个元素的大小
  35. int (*isNullOrEmpty)(struct myArrayOP*);//判断列表是否为空
  36. int (*insertHead)(struct myArrayOP*,void* obj);//在数组的头插入
  37. int (*inserTail)(struct myArrayOP*,void* obj);//在数组的末尾插入
  38. int (*delHead)(struct myArrayOP*);//删除数组的头
  39. int (*delTail)(struct myArrayOP*);//删除数组的尾
  40. void* (*delHeadNoFree)(struct myArrayOP*);//删除数组的头(不会自动调用free),会copy一份返回
  41. void* (*delTailNoFree)(struct myArrayOP*);//删除数组的尾(不会自动调用free),会copy一份返回
  42. int (*del)(struct myArrayOP*,unsigned int where);//在数组的where处删除某个对象(会自动调用free)
  43. void* (*delNoFree)(struct myArrayOP*,unsigned int where);//在数组的where处删除某个对象(不会自动调用free),会copy一份返回
  44. int (*insert)(struct myArrayOP*,unsigned int where,void* obj);//在数组的where处插入对象
  45. unsigned int (*index)(struct myArrayOP*,void* obj);//取该对象的数组下标
  46. unsigned int (*find)(struct myArrayOP*,void* obj,unsigned int times);//查找该对象times+1次,返回times+1次所对应的下标,times为0表示取第一个
  47. unsigned int (*findby)(struct myArrayOP*self,int(*cmp)(void*,void*),void*(*filed)(void*),void*target,unsigned int times);//使用cmp查找该对象的filed字段对应的target,times+1次,返回times+1次所对应的下标,times为0表示取第一个
  48. unsigned int (*unic) (struct myArrayOP*self,void*(*field)(void*),unsigned int times);//在数组上保证数组上某个对象最多不出现time+1次,filed函数应当返回特征字段的地址,size应当设置为特征的大小
  49. void* (*slice)(struct myArrayOP* self,unsigned int i);//切片函数,数组上的第i个对象
  50. void (*destory)(struct myArrayOP *self);//销毁数组,会释放所有的该数组上的对象
  51. // void (*destoryNoFree)(struct myArrayOP *self);
  52. void (*print)(struct myArrayOP * self);//使用.__str方法打印数组上的所有对象
  53. void (*_quickSort)(struct myArrayOP *self,long int start,long int end,int(*cmp)(void*, void*),void*(*filed)(void*),int reverse);//从start到end的快速排序
  54. void (*quickSort)(struct myArrayOP *self,int(*cmp)(void*, void*),void*(*filed)(void*),int reverse);//整个链表的快速排序,cmp方法返回给出的两个对象哪个更大,reverse为正则正序,为负则逆序,0不做排序
  55. int (*append)(struct myArrayOP*,void* data);//尾插
  56. void*  (*dequeue)(struct myArrayOP* self);//在数组上将第0个元素删除,将元素拷贝一份到新的堆空间并返回拷贝后的地址,需要手动free
  57. void*  (*pop)(struct myArrayOP* self);//在数组上将最后一个元素删除,将元素拷贝一份到新的堆空间并返回拷贝后的地址,需要手动free
  58. int  (*push)(struct myArrayOP*,void* data);//拷贝该元素到数组的最后一位
  59. int  (*queue)(struct myArrayOP*,void* data);//拷贝该元素到数组的最后一位
  60. unsigned int (*pack)(struct myArrayOP *self,char* buf,unsigned int length);//将其内部的数据打包成字节流
  61. struct myArrayOP* (*unpack)(struct myArrayOP *self,char* buf,void(*printData)(void*));//将字节流解包成内部数据,返回一个新的对象
  62. int (*delByAddr)(struct myArrayOP *self,void* obj);//按地址删除某一元素
  63. struct myArrayOP *(*copy)(struct myArrayOP *self);//拷贝副本
  64. struct myArrayOP *(*setter)(struct myArrayOP *self,struct myArrayOP *other);//将other的数据域拷贝至self的数据域
  65. } myArrayOP;
  66. //初始化函数
  67. myArrayOP* myArrayInit(unsigned int max_length,unsigned int size,void(*print)(void*));
  68. /*
  69. 将字节流解包成对象,会写入尾部的重复字节
  70. 字节流格式:unsigened short int used(2字节)unsigened short int datalen(2字节) data
  71. 如果pack_use_max_size != 0,使用used之后的2字节作为最大长度进行创建内存
  72. buf:缓冲区,字节流读取的地址
  73. printData:返回操作类初始化时需要的printData
  74. returnVal:操作类
  75. */
  76. myArrayOP* myArrayUnpack(char pack_use_max_size,char* buf,void(*printData)(void*));
  77. #endif
复制代码
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

美丽的神话

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表