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/