1 #define _CRT_SECURE_NO_WARNINGS
2 #include <stdio.h>
3 #include <stdlib.h>
4 #include <string.h>
5
6 typedef struct SimpleTextEditor
7 {
8 char* ch;
9 int len;
10 struct SimpleTextEditor* front;
11 struct SimpleTextEditor* rear;
12 int row;
13 }STE;
14
15 void Init(STE* head);
16 void Input(STE* head);
17 void Output(STE* head);
18 void Insert(STE* head);
19 void Delete(STE* head);
20 void Index(STE* head);
21 int* Get_Next(char* a);
22 int* Get_Nextval(char* a);
23 void Census(STE* head);
24 void Replace(STE* head);
25
26 int main(void)
27 {
28 int num = 0;
29
30 STE* head = (STE*)calloc(1, sizeof(STE));
31 Init(head);
32 while (1)
33 {
34
35 printf("****************************************************************\n");
36 printf("输入指令序号0.结束 1.写入(q退出) 2.插入 3.删除 4.替换 5.查找 6.统计:");
37 scanf("%d", &num);
38 getchar();
39 switch (num)
40 {
41 default:
42 continue;
43 case 0:
44 return 0;
45 case 1:
46 Input(head);
47 Output(head);
48 break;
49 case 2:
50 Output(head);
51 Insert(head);
52 Output(head);
53 break;
54 case 3:
55 Output(head);
56 Delete(head);
57 Output(head);
58 break;
59 case 4:
60 Output(head);
61 Replace(head);
62 Output(head);
63 break;
64 case 5:
65 Output(head);
66 Index(head);
67 getchar();
68 Output(head);
69 break;
70 case 6:
71 Output(head);
72 Census(head);
73 getchar();
74 Output(head);
75 break;
76 }
77 }
78 return 0;
79 }
80
81 void Init(STE* head)
82 {
83 head->ch = NULL;
84 head->len = 0;
85 head->front = NULL;
86 head->rear = NULL;
87 head->row = 0;
88 }
89
90 void Input(STE* head)
91 {
92 int i = 0;
93 char ch = '\0';
94 char a[255] = { '\0' };
95 STE* P;//新建行结点
96 STE* T = head;//行的尾结点
97
98 system("cls");
99 Output(head);
100 while (T->rear != NULL)
101 {
102 T = T->rear;
103 }
104
105 while(1)
106 {
107 P = (STE*)calloc(1, sizeof(STE));
108 P->front = T;
109 P->rear = T->rear;
110 P->row = T->row + 1;
111
112 printf("%d ", P->row);//行号
113 for (i = 0; (ch = getchar()) != '\n'; i++)
114 {
115 a[i] = ch;
116 }
117 if (0 == strcmp(a, "q"))//输入 q 结束输入
118 {
119 free(P);
120 break;
121 }
122
123 P->len = i;
124 P->ch = (char*)calloc(P->len, sizeof(char));//给每行申请定长的内存空间
125 for (i = 0; i < P->len; i++)
126 {
127 P->ch[i] = a[i];
128 a[i] = '\0';
129 }
130 T->rear = P;
131 T = P;
132 }
133 }
134
135 void Output(STE* head)
136 {
137 int i;
138 int j;
139 STE* P = head->rear;
140 system("cls");
141 printf("************************简易文本编辑器**************************\n");
142
143 for (i = 0; P != NULL; i++)
144 {
145 printf("%d ", i + 1);
146 for (j = 0; j < P->len; j++)
147 {
148 printf("%c", P->ch[j]);
149 }
150 printf("\n");
151 P = P->rear;
152 }
153 }
154
155 void Insert(STE* head)
156 {
157 int i = 0;
158 int j = 0;
159 char a[255] = { '\0' };
160 char ch;
161 int row;
162 int col;
163 char* temp = NULL;
164 STE* P = head;
165
166 printf("插入到第几行的第几个字符前(空格分隔)\n");
167 scanf("%d%*c%d", &row, &col);
168 getchar();
169 printf("插入内容是:");
170 while ((ch = getchar()) != '\n')
171 {
172 a[i++] = ch;
173 }
174
175 while (P->rear != NULL)
176 {
177 P = P->rear;
178 if (P->row == row)
179 {
180 temp = (char*)calloc(P->len + strlen(a), sizeof(char));
181 if (col <= 1)//行首插入
182 {
183 for (i = 0; a[i] != '\0'; i++)
184 {
185 temp[i] = a[i];
186 }
187 for (j = 0; j < P->len; j++)
188 {
189 temp[i + j] = P->ch[j];
190 }
191 }
192 else if (col > P->len)//行尾插入//bug
193 {
194 for (i = 0; i < P->len; i++)
195 {
196 temp[i] = P->ch[i];
197 }
198 for (i = 0; a[i] != '\0'; i++)
199 {
200 temp[i + P->len] = a[i];
201 }
202 }
203 else//行中第 col 位置插入
204 {
205 col = col - 1;//数组下标从0开始
206 for (i = 0; i < col; i++)
207 {
208 temp[i] = P->ch[i];
209 }
210 for (i = col; a[i - col] != '\0'; i++)
211 {
212 temp[i] = a[i - col];
213 }
214 for (; P->ch[i - strlen(a)] != '\0'; i++)
215 {
216 temp[i] = P->ch[i - strlen(a)];
217 }
218 }
219 P->ch = temp;
220 P->len += (int)strlen(a);
221 break;
222 }
223 }
224
225 if (P->rear == NULL && P->row != row)
226 {
227 printf("该行不存在!\n");
228 }
229 }
230
231 void Delete(STE* head)
232 {
233 int i;
234 int row;
235 int pos;
236 int len;
237 STE* P = head->rear;
238 char* temp = NULL;
239
240 printf("从第几行第几个位置开始删除几位(空格分隔)\n");
241 scanf("%d%*c%d%*c%d", &row, &pos, &len);
242 while (P != NULL)
243 {
244 if (P->row == row)
245 {
246 if (pos < 1 || pos > P->len || len > (P->len - pos + 1))
247 {
248 printf("删除参数非法!\n");
249 return;
250 }
251 else
252 {
253 if (pos == 1 && len == P->len)//删除整行
254 {
255 if (P->rear == NULL)//若删除最后一行
256 {
257 P->front->rear = NULL;
258 free(P);
259 return;
260 }
261 else
262 {
263 P->front->rear = P->rear;
264 P->rear->front = P->front;
265 free(P);
266
267 P = head->rear;
268 for (i = 1; P != NULL; i++)
269 {//修改全部行号
270 P->row = i;
271 P = P->rear;
272 }
273 return;
274 }
275 }
276
277 temp = (char*)calloc(P->len - len, sizeof(char));
278 pos = pos - 1;//数组下标从0开始
279 for (i = 0; i < pos; i++)//删除点之前部分
280 {
281 temp[i] = P->ch[i];
282 }
283 for (i = pos; i < P->len; i++)//删除后剩余部分
284 {
285 temp[i] = P->ch[i + len];
286 }
287 P->ch = temp;
288 P->len -= len;
289 return;
290 }
291 }
292 P = P->rear;
293 }
294 printf("该行不存在!\n");
295 return;
296 }
297
298 int* Get_Next(char* a)
299 {
300 int j = 0;
301 int k = -1;
302 int* next = NULL;
303 int len = 0;
304 while (a[++len] != '\0');//获得字符串 a 的长度 len
305 next = (int*)calloc(len, sizeof(int));
306
307 next[0] = -1;
308 while (j < len)
309 {
310 if (k == -1 || a[j] == a[k])
311 {
312 j++;
313 k++;
314 next[j] = k;
315 }
316 else
317 {
318 k = next[k];
319 }
320 }
321 return next;
322 }
323
324 int* Get_Nextval(char* a)
325 {
326 int j = 1;
327 int k = 0;
328 int len = 0;
329 int* next = Get_Next(a);
330 int* nextval;
331 while (a[++len] != '\0');
332 nextval = (int*)calloc(len, sizeof(int));
333
334 nextval[0] = -1;
335 while (j < len)
336 {
337 k = next[j];
338 if (a[j] == a[k])
339 {
340 nextval[j] = nextval[k];
341 }
342 else
343 {//失配,说明需要滑动到失配前的位置
344 nextval[j] = next[j];
345 }
346 j++;
347 }
348 return nextval;
349 }
350
351 void Index(STE* head)
352 {
353 int i = 0;
354 int j = 0;
355 int len = 0;
356 int count = 0;//匹配成功的次数
357 int* next = NULL;
358 int* nextval = NULL;
359 STE* P = head->rear;
360 char a[255] = { '\0' };
361 char ch = '\0';
362
363 printf("请输入查询内容:\n");
364 while ((ch = getchar()) != '\n')
365 {
366 a[i++] = ch;
367 }
368 len = i;
369 if (0 == len)
370 {
371 printf("查找内容不能为空");
372 return;
373 }
374
375 next = Get_Next(a);
376 nextval = Get_Nextval(a);
377
378 while (P != NULL)
379 {
380 i = 0;
381 while (i < P->len)
382 {
383 j = 0;
384 while (i < P->len && j < len)
385 {
386 if (j == -1 || P->ch[i] == a[j])
387 {
388 i++;
389 j++;
390 }
391 else
392 {
393 j = nextval[j];
394 }
395 }
396 if (j == len)//匹配成功
397 {
398 count++;
399 printf("count:%d %d(%d):", count, P->row, i - len + 1);
400 for (j = 0; j < P->len; j++)
401 {
402 printf("%c", P->ch[j]);
403 }
404 printf("\n");
405 }
406 }//该行已遍历
407 P = P->rear;
408 }//所有行已遍历
409 if (count == 0)
410 {
411 printf("文本中没有 %s\n", a);
412 }
413 }
414
415 void Census(STE* head)
416 {
417 int i;
418 int alpha = 0;//英文字母数
419 int punct = 0;//标点符号数
420 int space = 0;//空格数
421 STE* P = head->rear;
422
423 while (P != NULL)
424 {
425 for (i = 0; i < P->len; i++)
426 {
427 if ('A' <= P->ch[i] && P->ch[i] <= 'Z' || 'a' <= P->ch[i] && P->ch[i] <= 'z')
428 {
429 alpha++;
430 }
431 if ( 33 <= P->ch[i] && P->ch[i] <= 47 ||
432 58 <= P->ch[i] && P->ch[i] <= 64 ||
433 91 <= P->ch[i] && P->ch[i] <= 96 ||
434 123 <= P->ch[i] && P->ch[i] <= 126 )
435 {
436 punct++;
437 }
438 if (P->ch[i] == ' ')
439 {
440 space++;
441 }
442 if (P->ch[i] == '\t')
443 {
444 space += 4;
445 }
446 }
447 P = P->rear;
448 }
449 printf("英文字母数:%d\t标点符号数:%d\t空格数:%d\n", alpha, punct, space);
450 }
451
452 void Replace(STE* head)
453 {
454 int i;
455 int j;
456 int row = 0;
457 int pos = 0;
458 int len = 0;
459 int len_a = 0;
460 STE* P = head->rear;
461 char* temp = NULL;
462 char a[255] = { '\0' };
463
464 printf("在第几行第几位开始替换,替换几位(空格分隔)\n");
465 scanf("%d%*c%d%*c%d", &row, &pos, &len);
466 getchar();
467 printf("请输入要替换的内容\n");
468 scanf("%s", &a);
469 len_a = (int)strlen(a);
470 while (P != NULL)
471 {
472 if (P->row == row)
473 {
474 if (pos < 1 || pos > P->len || pos + len - 1 > P->len)
475 {
476 printf("替换目标不存在");
477 return;
478 }
479 else
480 {
481 temp = (char*)calloc(P->len - len + len_a, sizeof(char));
482 for (i = 0; i < pos - 1; i++)
483 {//替换前部分
484 temp[i] = P->ch[i];
485 }
486 for (j = 0; j < len_a; j++)
487 {//替换部分
488 temp[i++] = a[j];
489 }
490 for (j = 0; j < (P->len - pos - len + 2); j++)
491 {//替换后部分
492 temp[i++] = P->ch[j + pos + len - 1];
493 }
494 P->ch = temp;
495 P->len = i;
496 return;
497 }
498 }
499 else
500 {
501 P = P->rear;
502 }
503 }
504 printf("该行不存在!\n");
505 }