环形buffer缓冲区

 2023-09-13 阅读 17 评论 0

摘要: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࿰
  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 }

 

转载于:https://www.cnblogs.com/tyche116/p/8508089.html

版权声明:本站所有资料均为网友推荐收集整理而来,仅供学习和研究交流使用。

原文链接:https://hbdhgg.com/5/54328.html

发表评论:

本站为非赢利网站,部分文章来源或改编自互联网及其他公众平台,主要目的在于分享信息,版权归原作者所有,内容仅供读者参考,如有侵权请联系我们删除!

Copyright © 2022 匯編語言學習筆記 Inc. 保留所有权利。

底部版权信息