栈的简单应用-行编辑
程序员文章站
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 }