欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

栈的简单应用-行编辑

程序员文章站 2022-04-04 14:33:21
任何一个程序设计语言对应的编译程序都有如下几个主要部分组成: 词法分析、语法分析、语义分析、中间代码生成、代码优化、目标代码生成。 行编辑程序就是词法分析的内容。在编辑程序中,如果每次输入一个字符 就输入到计算机进行编辑太复杂。一般以行为单位来对文本进行编辑,这也是 在书写计算机程序指令时,一直遵循 ......

  任何一个程序设计语言对应的编译程序都有如下几个主要部分组成:

词法分析、语法分析、语义分析、中间代码生成、代码优化、目标代码生成。

  行编辑程序就是词法分析的内容。在编辑程序中,如果每次输入一个字符

就输入到计算机进行编辑太复杂。一般以行为单位来对文本进行编辑,这也是

在书写计算机程序指令时,一直遵循的每条语句用回车和换行符号来界定当前

语句结束的原因。  

  行编辑程序可以允许用户输入出差错,并改正。提高输入效率。

  合理的做法是:设立一个输入缓存区,用以接受用户输入的一行字符,然后

逐行存入用户数据区,并假设“#” 为退格符,“@” 为退行符。假设从终端接受了这

样两行字符:

      whli##ilr#e(s#*s)

      outchar@putchar(*s=#++)

则实际有效的是下列两行:

      while(*s)

      putchar(*s++)

   sqstack.h:

 1 #pragma once
 2 #include <stdio.h>
 3 #include <stdlib.h>
 4 #define stack_init_size 100//储存空间初始分配量
 5 #define stackincrement  10//存储空间分配增量
 6 #define ok 1
 7 #define error 0
 8 typedef char stacktype; //栈元素类型
 9 
10 typedef struct {
11     stacktype *base;   //在构造之前和销毁之后,base的值为null
12     stacktype *top;    //栈顶指针
13     int stacksize;     //当前已分配的存储空间,以元素为单位
14 }sqstack; //顺序栈
15 
16 //栈的初始化
17 int initstack(sqstack *p) {
18 
19 
20     p->base = (stacktype*)malloc(stack_init_size * sizeof(stacktype));
21     if (p->base == null)  return error;  //内存分配失败
22     p->top = p->base;     //栈顶与栈底相同表示一个空栈
23     p->stacksize = stack_init_size;
24     return ok;
25 
26 }
27 //判断栈是否为空
28 int emptystack(sqstack *p) {
29     //若为空栈 则返回ok,否则返回error
30     if (p->top == p->base) return ok;
31     else return error;
32 }
33 //顺序栈的压入
34 int push(sqstack *p, stacktype e) {
35     //插入元素e为新的栈顶元素
36     if ((p->top - p->base) >= p->stacksize)   //栈满,追加储存空间
37     {
38         p->base = (stacktype*)realloc(p->base, (p->stacksize + stackincrement) * sizeof(stacktype));
39         if (p->base == null)   return error;// 储存空间分配失败
40         p->top = p->base + p->stacksize;    //可能有人觉得这句有点多余(我当时也是这么想的 后面有解释)
41         p->stacksize += stackincrement;
42     }
43     *(p->top) = e;
44     (p->top)++;
45     return ok;
46 }
47 // 顺序栈的弹出     
48 int pop(sqstack *p, stacktype *e) {
49     //若栈不空,则删除p的栈顶元素,用e返回其值
50     if (p->top == p->base) return error;
51     --(p->top);
52     *e = *(p->top);
53     return ok;
54 
55 
56 }
57 //将顺序栈置空 栈还是存在的,栈中的元素也存在,
58 //如果有栈中元素的地址任然能调用
59 int clearstack(sqstack *p) {
60     p->top = p->base;
61     return ok;
62 }
63 //顺序栈的销毁
64 int destroystack(sqstack *p) {
65     //释放栈底空间并置空
66     free(p->base);
67     p->base = null;
68     p->top = null;
69     p->stacksize = 0;
70 
71     return ok;
72 }
73 //从栈顶到栈底对每个元素调用某个函数
74 int stacktraverse(sqstack p, void(*pfun)(stacktype)/*函数指针*/) {
75     //从栈底到栈顶依次对栈中的每个元素调用函数pfun()
76     while (p.top > p.base)
77         pfun(*(p.base)++);              //先调用后递增
78     
79     return ok;
80 }
81 //复制栈中元素到文件中
82 void copy(stacktype stack) {
83     file *fp = fopen("1.txt", "a+");
84     fputc(stack, fp);
85     
86 }

  源代码:

 1 #include <stdio.h>
 2 #include <stdlib.h>
 3 #include <math.h>
 4 #include "sqstack.h" //引入顺序栈储存结构及其基本操作
 5 #define ok 1
 6 #define error 0
 7 void lineedit()
 8 {
 9     //利用字符栈s,从终端接收一行并送至调用过程的数据区
10     file *fp = fopen("1.txt", "a+");
11     sqstack *s=(sqstack*)malloc(sizeof(sqstack));
12     char ch, *c=(stacktype*)malloc(sizeof(stacktype));
13     initstack(s); //构造空栈
14     printf("请输入一个文本文件,ctrl+z结束输入,#退格,@清空当前行:\n");
15     ch = getchar();  //从终端接受第一个字符
16     while (ch != eof)  //eof为ctrl+z,全文结束符
17     {
18         while (ch != eof && ch != '\n')  //行结束或全文结束
19         {
20             switch (ch)
21             {case'#':
22                 pop(s, c); break;  //仅当栈非空时退栈
23             case'@':
24                 clearstack(s); break; //清空栈
25             default:push(s, ch);//有效字符入栈
26 
27             
28             }
29             ch = getchar();//读取下一个字符
30          }
31         stacktraverse(*s, copy); //将栈内字符传送至文件
32         clearstack(s);
33         file *fp = fopen("1.txt", "a+");
34         fputc('\n', fp);
35         if (ch != eof) ch = getchar();
36     }
37 
38     destroystack(s);
39 
40 
41 
42     }
43 
44 
45 
46 
47 
48 
49 int main() 
50 {
51     file *fp = fopen("1.txt", "w"); //当前目录建立1文件,用于写数据
52     if (fp)
53     {
54         lineedit();
55         fclose(fp);
56     }
57     else
58         printf("建立文件失败!\n");
59     
60     return 0;
61 
62 }