9、蛤蟆的数据结构笔记之九栈的应用之行编辑实现
本篇名言:“人生照例是一场值得一搏的争衡,然而它的奖品是拼斗。”
继续栈结构的应用,行编辑。
欢迎转载,转载请标明出处:
1. 行编辑
行编辑的功能是接受用户从终端输入的程序或数据。每接受一个字符即存入用户数据区的做法不是最恰当的。好的做法是建立一个缓存区,允许洪湖输入出错,并在发现有无时可以及时更正。用栈来实现这个输入缓冲区是非常适合的。
每当从终端接受了一个字符后先作判别,如果不是退格符也不是退行符,则将该字符压入栈顶;如果是退格符则从栈顶去除一个字符,如果是退行符,则将字符栈清空。
2. 压栈出栈
基本和之前的例子相似,可以再源码中查看。
Status Push(SqStack *S,SElemType
e)
{
if(S->top-S->base>=S->stacksize)
return ERROR;
*S->top++=e;
return OK;
}
SElemType Pop(SqStack *S)
{
chare;
if(S->top==S->base)
return0;
e=*--S->top;
returne;
}
3. LineEdit()
LineEdit函数是本栈应用的核心。主要逻辑是:
输入字符,判断是否为EOF,如果不是则判断是否是回车,如果是EOF则退出程序,如果是\n,则退出子循环(第二个while循环),如果都不是则对字符进行选择处理,#删除一个字符,@删除整行字符,其他则入栈保存,等出现回车或者EOD(CTRL+C)时候进行输出。
void LineEdit()
{//利用字符栈S,从终端接收一行并传送至调用过程的数据区。
chart;
InitStack(&S);
InitStack(&S1);
ch=getchar();
while(ch!=EOF){//EOF为全文结束符
while(ch!=EOF&&ch!=‘\n‘){
switch(ch){
case ‘#‘:Pop(&S);break;//仅当栈非空时退栈
case ‘@‘:{while(!StackEmpty(&S))Pop(&S);};break;//构造空栈S
default:Push(&S,ch);break;//有效字符进栈,未考虑栈满情形
}
ch=getchar();//从终端接收下一字符
}
while(!StackEmpty(&S)){
t=Pop(&S);
Push(&S1,t);
}
printf("echo:>");
while(!StackEmpty(&S1)){
t=Pop(&S1);
printf("%c",t);
}
printf("\n");
if(ch!=EOF)ch=getchar();
}
DestoryStack(&S);
DestoryStack(&S1);
}
4. Main函数
Main只调用LineEdit函数,最后如下图1 所示
void main()
{
LineEdit();
}
5. 源码
#include
"stdio.h"
#include
"string.h"
#include
"stdlib.h"
#define
STACK_INIT_SIZE100
#define
OVERFLOW 0
#define
OK 1
#define
ERROR 0
typedef
int
Status;
typedef
char
SElemType;
typedef
struct
SqStack{
SElemType*base;
SElemType*top;
intstacksize;
}SqStack;
//初始化栈
SqStack S,S1;
char ch,c;
Status InitStack(SqStack *S)
{
S->base=(SElemType*)malloc(STACK_INIT_SIZE*sizeof(SElemType));
if(!S->base)exit(OVERFLOW);
S->top=S->base;
S->stacksize=STACK_INIT_SIZE;
return OK;
}
void DestoryStack(SqStack *S)
{//栈的销毁
free(S->base);
S->stacksize=0;
}
void ClearStack(SqStack *S)//栈的清空
{
S->stacksize=0;
}
Status StackEmpty(SqStack *S)//判断栈是否为空
{
if(S->top==S->base)
return1;
else
return0;
}
int StackLength(SqStack
S)
{//栈的长度 求栈里有多少个元素
return S.top-S.base;
}
Status GetTop(SqStack
S,SElemType
e)
{//取栈顶元素
if(S.top==S.base)return
ERROR;
e=*(S.top-1);
return OK;
}//GetTop
Status Push(SqStack *S,SElemType
e)
{
if(S->top-S->base>=S->stacksize)
return ERROR;
*S->top++=e;
return OK;
}
SElemType Pop(SqStack *S)
{
chare;
if(S->top==S->base)
return0;
e=*--S->top;
returne;
}
void LineEdit()
{//利用字符栈S,从终端接收一行并传送至调用过程的数据区。
chart;
InitStack(&S);
InitStack(&S1);
ch=getchar();
while(ch!=EOF){//EOF为全文结束符
while(ch!=EOF&&ch!=‘\n‘){
switch(ch){
case ‘#‘:Pop(&S);break;//仅当栈非空时退栈
case ‘@‘:{while(!StackEmpty(&S))Pop(&S);};break;//构造空栈S
default:Push(&S,ch);break;//有效字符进栈,未考虑栈满情形
}
ch=getchar();//从终端接收下一字符
}
while(!StackEmpty(&S)){
t=Pop(&S);
Push(&S1,t);
}
printf("echo:>");
while(!StackEmpty(&S1)){
t=Pop(&S1);
printf("%c",t);
}
printf("\n");
if(ch!=EOF)ch=getchar();
}
DestoryStack(&S);
DestoryStack(&S1);
}
void main()
{
LineEdit();
}