• 环形buffer缓冲区


      1 #include <stdio.h>
      2 #include <string.h>
      3 #include <malloc.h>
      4 
      5 struct CircleBuf
      6 {
      7     char *pFirst;//指向循环表开始的位置
      8     char *pLast;//指向循环表结尾的位置
      9     char *plSave;//指向最后一个存数据的后一位,没有数据为NULL,或与pfsave相等
     10     char *pfSave;//指向第一个存数据的位置,没有数据为NULL,或与plsave相等
     11     int iSize;//循环表的大小
     12     int iDataNum;//存数据的大小
     13 };
     14 
     15 int InitCircleBuf(struct CircleBuf *buf, const int bufSize)
     16 //初始化缓冲区。buf为目标缓冲区。字节数为bufSize,能存储bufSize 个字符
     17 //操作成功返回1,操作失败返回0.
     18 {
     19     buf->pFirst = (char*)malloc((bufSize + 1)*(sizeof(char)));//初始化CiecleLink
     20     if(NULL == buf->pFirst)
     21     {
     22         printf("\nMemory allocation failure !\n");
     23         return 0;
     24     }
     25     buf->iSize = bufSize;
     26     buf->iDataNum = 0;
     27     buf->pfSave = NULL;
     28     buf->plSave = NULL;
     29     buf->pLast = buf->pFirst + buf->iSize;
     30     return 1;
     31 }
     32 
     33 void DestroyCircleBuf(struct CircleBuf *buf)
     34 //销毁环形缓冲区
     35 {
     36     free(buf->pFirst);
     37     buf->iDataNum = 0;
     38     buf->iSize = 0;
     39     buf->pFirst = NULL;
     40     buf->pLast = NULL;
     41     buf->plSave = NULL;
     42     buf->pfSave = NULL;
     43 }
     44 
     45 void ClearCircleBuf(struct CircleBuf *buf)
     46 //清空环形缓冲区
     47 {
     48     buf->plSave = NULL;
     49     buf->pfSave = NULL;
     50     buf->iDataNum = 0;
     51 }
     52 
     53 int InCircleBuf(struct CircleBuf *buf, char *str, int length)
     54 //向循环表存入数据。buf为目标循环表,str为源字符串地址,存入的字节数为length
     55 //操作成功返回 1, 操作失败返回 0
     56 {
     57     int i;
     58     int j;
     59     int len;
     60     int lengthtem;
     61     len = strlen(str);
     62     if(len < length)
     63     {
     64         printf("the length is longer then the size of str !\n");
     65         return 0;
     66 
     67     }
     68 
     69     if((NULL == buf->pfSave) &&(NULL == buf->plSave))//CircleBuf为空时
     70     {
     71         if(length > (buf->iSize - 1))
     72         {
     73             printf("length is longer then the size of Circlebuf !\n");
     74             return 0;
     75         }
     76         else
     77         {
     78 
     79             strncpy(buf->pFirst, str, length);
     80             buf->pfSave = buf->pFirst;
     81             buf->plSave = buf->pfSave + length;
     82             buf->iDataNum += length;
     83 
     84         }
     85     }
     86     else if(buf->pfSave <= buf->plSave)//pfsave小于或等于plsave,存数据没有超过结尾处
     87     {
     88 
     89         if(length < (buf->pLast - buf->plSave + 1))//存数据的length没有达到CircleBuf结尾
     90         {
     91 
     92             strncpy(buf->plSave, str, length);
     93             buf->iDataNum += length;
     94             buf->plSave += length;
     95         }
     96         else if(length == (buf->pLast - buf->plSave + 1))//存数据的length刚好到CircleBuf结尾处
     97         {
     98 
     99             if(buf->pfSave > buf->pFirst)
    100             {
    101                 strncpy(buf->plSave, str, length);
    102                 buf->iDataNum += length;
    103                 buf->plSave = buf->pFirst;
    104             }
    105             else
    106             {
    107                 printf("the length is longer then the unused space !\n");
    108                 return 0;
    109             }
    110         }
    111         else   //存数据的length长度超过CircleBuf结尾
    112         {
    113 
    114             if(length > ((buf->pLast - buf->plSave)+(buf->pfSave - buf->pFirst)))
    115                 //存数据的length大于剩余空间大小
    116             {
    117                 printf("length is too long then the unused space!\n");
    118                 return 0;
    119             }
    120             else  //存数据的length小于剩余空间大小,将length长度数据分两次存
    121             {
    122 
    123                 lengthtem = length - (buf->pLast - buf->plSave + 1);
    124                 for(i=0; i<(buf->pLast - buf->plSave + 1); i++)
    125                 {
    126                     *(buf->plSave + i) = str[i];
    127 
    128                 }
    129                 buf->plSave = buf->pFirst;
    130 
    131                 for(j=0; j<lengthtem; j++)
    132                 {
    133                     *(buf->plSave + j) = str[i + j];
    134 
    135                 }
    136 
    137                 buf->plSave += j;
    138                 buf->iDataNum += length;
    139 
    140             }
    141         }
    142     }
    143     else if(buf->pfSave > buf->plSave)//pfsave大于plsave,存数据超过结尾处,至少绕了一圈
    144     {
    145         if(length > (buf->pfSave - buf->plSave))//存数据的length大于剩余空间大小
    146         {
    147             printf("length is too long then the unsued space!\n");
    148             return 0;
    149         }
    150         else
    151         {
    152             strncpy(buf->plSave, str, length);
    153             buf->iDataNum += length;
    154             buf->plSave += length;
    155         }
    156     }
    157     return 1;
    158 }
    159 
    160 
    161 int OutCircleBuf(char *str, struct CircleBuf *buf, int length)
    162 //从循环表中取数据。 str为目标字符串地址, buf为源循环表, 取出的字节数为length
    163 //操作成功返回 1, 操作失败返回 0
    164 {
    165     int i;
    166     int j;
    167     int lengthtem;
    168 
    169     if((NULL == buf->pfSave) &&(NULL == buf->plSave))//CircleBuf为空
    170     {
    171         printf("the Circlebuf is empty !\n");
    172         return 0;
    173     }
    174 
    175     if(buf->pfSave < buf->plSave)//pfsave小于plsave,存的数据没有超过结尾
    176     {
    177         if((buf->pfSave + length) > buf->plSave)
    178         {
    179             printf("length is longer then the used of Circlebuf !\n");
    180             return 0;
    181         }
    182         else
    183         {
    184             strncpy(str, buf->pfSave, length);
    185             buf->pfSave += length;
    186             buf->iDataNum -= length;
    187         }
    188     }
    189     else if(buf->pfSave == buf->plSave)//pfsave等于plsave,CircleBuf为空
    190     {
    191         printf("there is no data in Circlebuf !\n");
    192         return 0;
    193     }
    194     else if(buf->pfSave > buf->plSave)//pfsave大于plsave,存的数据超过结尾,至少绕了一圈
    195     {
    196 
    197         if(length < (buf->pLast - buf->pfSave + 1))//取数据的length没到结尾
    198         {
    199             strncpy(str, buf->pfSave, length);
    200             buf->pfSave += length;
    201             buf->iDataNum -= length;
    202         }
    203         else if(length == (buf->pLast - buf->pfSave + 1))//取数据的length刚好达到结尾处
    204         {
    205             strncpy(str, buf->pfSave, length);
    206             buf->pfSave = buf->pFirst;
    207             buf->iDataNum -= length;
    208         }
    209         else //取数据的length超过结尾
    210         {
    211 
    212             if((length - (buf->pLast - buf->pfSave + 1)) > (buf->plSave - buf->pFirst))
    213             //取数据的length大于剩余数据的大小
    214             {
    215                 printf("%d\n",(buf->plSave - buf->pFirst));
    216                 printf("the used data is shorter then length !\n");
    217                 return 0;
    218             }
    219             else //取数据的length小于剩余数据的大小,将数据分开两次取出来
    220             {
    221                 lengthtem = length - (buf->pLast - buf->pfSave + 1);
    222                 for(i=0; i<(buf->pLast - buf->pfSave + 1); i++)
    223                 {
    224                     str[i] = *(buf->pfSave +i);
    225                 }
    226                 buf->pfSave = buf->pFirst;
    227                 for(j=0; j<lengthtem; j++)
    228                 {
    229                     str[i + j] = *(buf->pfSave + j);
    230                 }
    231                 buf->pfSave += j;
    232                 buf->iDataNum -= length;
    233             }
    234         }
    235     }
    236     str[length] = '\0';
    237     return 1;
    238 }
    239 
    240 int CalDataNumCB(struct CircleBuf *buf)
    241 //计算循环表的数据个数。buf为目标循环表
    242 //返回已存放数据的字节数
    243 {
    244     return buf->iDataNum;
    245 }
    246 
    247 int CalSpaceNumCB(struct CircleBuf *buf)
    248 //计算循环表的剩余空间大小。 buf为目标循环表
    249 //返回剩余空间字节数
    250 {
    251     return (buf->iSize - buf->iDataNum);
    252 }
    253 
    254 
    255 int OutCBtoFile(char *filename, struct CircleBuf *buf)
    256 //将循环表中所有的数据都存到所给的文件中,filename为目标文件的路径及名称,buf为源循环表。
    257 //操作成功返回 1, 操作失败返回 0
    258 {
    259     FILE *fp;
    260     int i;
    261     int length;
    262     char ch[2];
    263     if(NULL == (fp = fopen(filename, "wt+")))//判断文件是否打开
    264     {
    265         printf("can't open %s !\n", filename);
    266         return 0;
    267     }
    268     length = CalDataNumCB(buf);
    269 
    270 
    271     for(i=0; i<length; i++)        //将全部数据读入文件中
    272     {
    273         OutCircleBuf(ch, buf, 1);
    274         printf("%d   %c   \n", strlen(ch), ch[0]);
    275         fwrite(ch, 1, 1, fp);
    276 
    277     }
    278 
    279     fclose(fp);
    280     return 1;
    281 }
    282 
    283 
    284 int InCBfromFile(struct CircleBuf *buf, char *filename)
    285 //将文件中的数据读到循环链表中,clink为目标链表,filename为源文件的路径及名称。
    286 //操作失败返回0, 文件数据全部存储完毕返回1, clink空间不足,只存入部分数据返回-1
    287 {
    288     FILE *fp;
    289     int length;
    290     char ch;
    291 
    292     if(NULL == (fp = fopen(filename, "rt+")))// 文件打开失败
    293     {
    294         printf("can't open %s !\n", filename);
    295         return 0;
    296     }
    297     else
    298     {
    299         length = CalSpaceNumCB(buf);
    300         if(0 == length)                     //循环表数据已满
    301         {
    302             printf("CircleLink is full!\n");
    303             return 0;
    304         }
    305         else
    306         {
    307             while(1)
    308             {
    309                 if(0 == length )           //循环表空间已满,还有部分数据未读入
    310                 {
    311                     printf("CircleBuf is full, some data still in file %s !\n", filename);
    312                     return -1;
    313                 }
    314                 else
    315                 {
    316                     ch = fgetc(fp);
    317                     if(ch == EOF)
    318                     {
    319                         printf("file %s is over, data are in Circlebuf now!\n", filename);
    320                                           //文件数据全部读完,并存入表中
    321                         return 1;
    322                     }
    323                     else
    324                     {
    325 
    326                         InCircleBuf(buf, &ch, 1);
    327                         length--;
    328                     }
    329 
    330                 }
    331 
    332             }
    333 
    334         }
    335     }
    336     return 1;
    337 }
  • 相关阅读:
    JS图片宽度自适应移动端
    SQL语句中drop、truncate和delete的用法
    C#求百分比
    JS刷新后回到页面顶部
    JS返回上一页并刷新代码整理
    jQuery 获取设置图片 src 的路径
    C#银行卡号每隔4位数字加一个空格
    input标签内容改变时触发事件
    C#的Split()方法
    数据库常见性能问题调优
  • 原文地址:https://www.cnblogs.com/tyche116/p/8508089.html
Copyright © 2020-2023  润新知