数据结构C语言版_栈实现行编辑程序

#include
#include
#include
/*
数据结构C语言版 栈实现行编辑程序
P49-P50
编译环境:Dev-C++ 4.9.9.2
日期:2011年2月12日
*/

typedef char SElemType; // 栈的元素类型

#define STACK_INIT_SIZE 10 // 存储空间初始分配量
#define STACKINCREMENT 2 // 存储空间分配增量
// 栈的顺序存储表示 P46
typedef struct SqStack
{
SElemType *base; // 在栈构造之前和销毁之后,base的值为NULL
SElemType *top; // 栈顶指针
int stacksize; // 当前已分配的存储空间,以元素为单位
}SqStack; // 顺序栈

FILE *fp;


// 构造一个空栈S。
int InitStack(SqStack *S)
{
// 为栈底分配一个指定大小的存储空间
(*S).base = (SElemType *)malloc(STACK_INIT_SIZE*sizeof(SElemType));
if( !(*S).base )
exit(0); // 存储分配失败
(*S).top = (*S).base; // 栈底与栈顶相同表示一个空栈
(*S).stacksize = STACK_INIT_SIZE;
return 1;
}

// 销毁栈S,S不再存在。
int DestroyStack(SqStack *S)
{
free((*S).base); //释放栈底的空间,并置空
(*S).base = NULL;
(*S).top = NULL;
(*S).stacksize = 0;
return 1;
}

// 把S置为空栈。
int ClearStack(SqStack *S)
{
(*S).top = (*S).base; //栈底栈顶相同为空栈
return 1;
}

// 插入元素e为新的栈顶元素。
int Push(SqStack *S, SElemType e)
{
if((*S).top - (*S).base >= (*S).stacksize) // 栈满,追加存储空间
{
(*S).base = (SElemType *)realloc((*S).base,
((*S).stacksize + STACKINCREMENT) * sizeof(SElemType));
if( !(*S).base )
exit(0); // 存储分配失败
(*S).top = (*S).base+(*S).stacksize;
(*S).stacksize += STACKINCREMENT;
}
*((*S).top)++=e;
// 这个等式的++ * 优先级相同,但是它们的运算方式,是自右向左
return 1;
}

// 若栈不空,则删除S的栈顶元素,用e返回其值,并返回1;否则返回0。
int Pop(SqStack *S,SElemType *e)
{
if((*S).top == (*S).base)
return 0;
*e = *--(*S).top;
// 这个等式的++ * 优先级相同,但是它们的运算方式,是自右向左
return 1;
}

// 从栈底到栈顶依次对栈中每个元素调用函数visit()。
int StackTraverse(SqStack S,int(*visit)(SElemType))
{
while(S.top>S.base)
visit(*S.base++);
printf("\n");
return 1;
}

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

// 算法3.2 P50
// 利用字符栈s,从终端接收一行并送至调用过程的数据区。
void LineEdit()
{
SqStack s;
char ch,c;

InitStack(&s);
printf("请输入一个文本文件,ctrl+z结束输入,#退格,@清空当前行:\n");
ch = getchar();
while(ch != EOF) // EOF为Ctrl + z键,全文结束符
{
while(ch != EOF && ch != '\n')
{
switch(ch)
{
case '#':
Pop(&s, &c);
break; // 仅当栈非空时退栈
case '@':
ClearStack(&s);
break; // 重置s为

空栈
default :
Push(&s,ch); // 有效字符进栈
}
ch=getchar(); // 从终端接收下一个字符
}
StackTraverse(s,copy); // 将从栈底到栈顶的栈内字符传送至文件
ClearStack(&s); // 重置s为空栈
fputc('\n', fp);
if(ch != EOF)
ch = getchar();
}
DestroyStack(&s);
}

int main()
{
fp = fopen("1", "w"); // 在当前目录下建立1文件,用于写数据,
if( fp ) // 如已有同名文件则先删除原文件
{
LineEdit();
fclose(fp); // 关闭fp所指的文件
}
else
printf("建立文件失败!\n");

system("pause");
return 0;
}

/*
输出效果:

请输入一个文本文件,ctrl+z结束输入,#退格,@清空当前行:
whli##ilr#e(s#*s)

outcha@putchar(*s=#++);


请按任意键继续. . .

下面是"1"中的内容:

while(*s)
putchar(*s++);


*/

相关文档
最新文档