栈的应用(行编辑程序)

基本原理:


为此,可设置个输入缓冲区为一个栈结构,每当从终端接受一个字符后先作如下判别,如果它既不是退格符也不是退行符,则将该字符压入栈顶;如果是一个退格符,则从栈顶删除一个字符;如果它是一个退行符,则将字符栈清为空。


/*
	这是一个利用栈来实现编辑的小程序,#时则前一个字符无效,@时表示输入的整行字符无效;
*/
#include <stdio.h>
#include <stdlib.h>
#define STACT_INIT_SIZE 10			//存储空间初始分配量
#define STACKINCREMNET 2			//存储空间分配增量
#define MAX 80
typedef int SElemType;
typedef enum {true = 1, false = 0}bool;

FILE *fp;							//将文件指针fp声明为全局变量
//栈的结构类型
typedef struct SqStack
{
	SElemType *base;				//在构造之前和销毁之后,base的值为NULL
	SElemType *top;					//栈顶指针
	int stacksize;					//当前已分配的存储空间,以元素为单位
}SqStack;

static bool InitStack(SqStack *s);
static bool StackEmpty(SqStack *s);
static bool PushStack(SqStack *s, SElemType e);
static bool PopStack(SqStack *s, SElemType *value);
static bool ClearStack (SqStack *s);
static bool StackTraverse(SqStack *s, int *c);
static bool DestroyStack(SqStack *s);
static void LineEdit();
static bool copy (SElemType c);

int main(void)
{
	fp = fopen("EDT.txt", "w");						//打开一个文件,如果没有,则创建
	if (fp != NULL)
	{
		LineEdit();
		fclose(fp);
	}
	else
	{
		puts("建立文件失败!");
	}
	return 0;
}

static bool InitStack(SqStack *s)
{
	//分配存储空间,来存放SElemType类型的元素
	s->base = (SElemType *) malloc (STACT_INIT_SIZE * sizeof(SElemType));
	if (!s->base)
	{
		return false;
		exit(-1);
	}
	//空栈时,栈顶指针和栈底指针指向同一个位置
	s->top = s->base;
	s->stacksize = STACT_INIT_SIZE;
	return true;
}

static bool PushStack(SqStack *s, SElemType e)
{
	
	//如果栈已满,则需要重新分配内存
	if ((s->top-s->base) >= s->stacksize)
	{
		s->base = (SElemType *) realloc (s->base, (s->stacksize + STACKINCREMNET)*sizeof(SElemType));
		if (!s->base)
		{
			return false;
			exit(-1);
		}
		s->top = s->base + s->stacksize;
		s->stacksize += STACKINCREMNET;
	}
	*s->top++ = e;
	return true;
}



static bool PopStack(SqStack *s, SElemType *value)
{
	if (s->top == s->base)
	{
		puts("stack is empty");
		return false;
	}
	*value = *(--s->top);
	printf("现在出栈的数值是:%c\n", *value);
	return true;
}

static bool StackEmpty(SqStack *s)
{
	if (s->top == s->base)
	{
		return true;
	} 
	else
	{
		return false;
	}
}

static bool ClearStack (SqStack *s)
{
	s->top = s->base;
	return true;
}


//栈必须从顶部开始出栈,
static bool StackTraverse(SqStack *s, int *c)
{
	SElemType *p = NULL;			
	p = s->top;							//是为了保护这个栈,不让这个栈变成空栈
	while(s->top > s->base)
	{
		*c = *(--s->top);
		printf("%d", *c);
	}
	s->top = p;							//栈遍历结束后,将top重新指向栈顶的位置
	putchar('\n');
	return true;
}
//销毁这个栈
static bool DestroyStack (SqStack *s)
{
	free(s->base);
	s->base = NULL;
	s->top = NULL;
	s->stacksize = 0;

	return true;
}

static bool copy (SElemType c)
{
	//将字符送至fp所指的文件中
	fputc(c, fp);
	return true;
}

static void LineEdit()
{
	/*为什么这里需要两个栈,因为存入第一个栈后,它的字母顺序为逆序的,为了正序输入,需要另外一个
	栈来实行第二次的逆序
	*/
	SqStack s;
	SqStack s_temp;
	static SElemType pop_value = 0;
	static SElemType temp_value = 0;
	char ch;					//用来存放终端输入的字符
	int c;

	InitStack(&s);
	InitStack(&s_temp);
	puts("请输入一个文本文件,~z结束输入:");
	//从终端读入字符
	ch = getchar();
	while (ch != EOF)							//如果是EOF则推出整个循环
	{
		while (ch!=EOF && ch!='\n')
		{
			switch(ch)
			{
			case '#':
				if (!StackEmpty(&s))				//仅当栈非空时退栈
				{
					PopStack(&s, &c);
					break;							//跳出switch循环
				}
				else
				{
					puts("# error");
					break;
				}
			case '@':ClearStack(&s);				//重置s为空栈
				break;
			default:PushStack(&s, ch);				//有效字符进栈
			}
			ch = getchar();						//从终端接收下一个字符
		}
		while (s.top > s.base)
		{
			//将从第一个栈底到栈顶的栈内字符传送至第二个栈
			PopStack(&s, &pop_value);
			PushStack(&s_temp, pop_value);
		}
		//将第二个栈的内容输入到文件中去
		while(s_temp.top > s_temp.base)
		{
			PopStack(&s_temp, &temp_value);
			fputc(temp_value, fp);
		}
		ClearStack(&s);
		ClearStack(&s_temp);
		fputc('\n', fp);
		if (ch != EOF)
		{
			ch = getchar();
		}
	}
	DestroyStack(&s);
	DestroyStack(&s_temp);
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值