用栈实现简单的行编辑器

来源:互联网 发布:武汉网络公关 编辑:程序博客网 时间:2024/06/10 01:59

所谓简单的行编辑器,描述如下:

接受用户从终端输入的程序或数据,并将最后结果显示到屏幕上。由于用户输入时,不能保证不出差错,因此,若在编辑程序中,“每接受一个字符即输出到屏幕上“的做法显然不恰当。较好的做法是,设立一个输入缓冲区,用以接受用户输入的一行字符,然后一次性将其显示到屏幕上。允许用户 输入出错并及时改正。以”#“表示退格,删除上一个字符。以”@“表示退行,删除一整行。例如接受如下两行字符:

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

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

最终有效的是下列两行:

while(*s)

putchar(J*s++);

因此,可以给这个缓冲区为一个栈结构,每当c从终端接受了一个字符之后先作如下判别:如果它既不是退格符也不是退行符,则将其压栈;如果是一个退格符,则从栈顶删除一个元素;如果是退行符,则清空栈。

代码如下:

1.头文件:line_editor.h:

//Headfile
//    line editor
//History
//    Xinspace    7 Mar    First release

#ifndef xinspace_
#define xinspace_

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <fcntl.h>

#include <sys/stat.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <netinet/ip.h>

#include <pthread.h>

#define error_show(function)    \
do  \
{   \
fprintf(stderr, “in file:%s, in function:%s, at line %d, %s : %s\n”, __FILE__, __FUNCTION__, __LINE__, function, strerror(errno));    \
exit(-1);   \
}while(0)

#define MAX 200 //缓冲区最大能存的元素数
void start();//开始函数

char *create_stack();//创建空栈
char pop(char *st, char *sb);//出栈
void push(char *st, char pa);//压栈
void clear_stack(char **st, char *sb);//清空栈

#endif

 

2.主函数:main.c:

//Program
//    line editor
//History
//    Xinspace    7 Mar    First release

#include “line_editor.h”

int main(void)
{
char con = ‘y’;//当选项con变量为y或者Y时,可以循环调用start函数,否则就退出程序。
while(1)
{
if(con == ‘y’ || con == ‘Y’)
start();
else
break;
printf(“continue?y/n\n”);
con = getchar();
getchar();
}
return 0;
}

 

3.附加文件:line_editor.c

//Program
//    line editor
//History
//    Xinspace    7 Mar    First release

#include “line_editor.h”

void start()//开始函数,建空栈,并检查输入的字符是否为退行符,退格符或正常字符,然后执行相应的操作
{
printf(“input strings:\n”);
char buf[MAX] = {0};
char *buf_start = buf;//当输入的字符中有换行符时,编辑器就要把栈中的所以字符发送到缓冲区中buf中,buf_start是用来标明栈的元素发送到缓冲区的哪一段
char ch; //要输入的字符存在ch中
char *st, *sb;//st栈顶指针,sb栈底指针
st = sb = create_stack();

ch = getchar();
while(ch != EOF)//EOF是输入文件结束符
{
while(ch != EOF && ch != ‘\n’)
{
switch(ch)
{
case ‘#’:
pop(–st, sb);
break;
case ‘@’:
clear_stack(&st, sb);
break;
default:
push(st++, ch);
}
ch = getchar();
}
sprintf(buf_start, sb);//将栈中的元素发送到buf缓冲区中的某一段
buf_start += strlen(sb);//改变段的起始地址,使新一轮的发送与缓冲区当前存在的字符不互相覆盖
*buf_start++ = ‘\n’;//在这里填加换行,因为刚刚发现字符中有换行符,这里把这个换行符补上
clear_stack(&st, sb);
if(ch != EOF)
ch = getchar();
}
puts(buf);
clear_stack(&buf_start, buf);
}

char *create_stack()
{
char *sp = (char *)malloc(sizeof(char) * MAX);
if(!sp)
error_show(“malloc”);

return sp;
}

char pop(char *st, char *sb)
{
if(st < sb)
{
fprintf(stderr, “the stack is NULL!\n”);
return 0;
}

char ch = *st;
*st = ‘\0′;
return ch;
}

void push(char *st, char ch)
{
*st = ch;
}

void clear_stack(char **st, char *sb)
{
while(*st != sb)
pop(–*st, sb);
**st = ‘\0′;
}

 

这个程序实现起来还是比较简单的。大家看看代码就明白了。多是栈的用法。


更多文章请见http://blog.xinspace.name

三个文件的下载地址:

main.c

line_editor.h

line_editor.c

原创粉丝点击