zoukankan      html  css  js  c++  java
  • 栈的简单应用-行编辑

      任何一个程序设计语言对应的编译程序都有如下几个主要部分组成:

    词法分析、语法分析、语义分析、中间代码生成、代码优化、目标代码生成。

      行编辑程序就是词法分析的内容。在编辑程序中,如果每次输入一个字符

    就输入到计算机进行编辑太复杂。一般以行为单位来对文本进行编辑,这也是

    在书写计算机程序指令时,一直遵循的每条语句用回车和换行符号来界定当前

    语句结束的原因。  

      行编辑程序可以允许用户输入出差错,并改正。提高输入效率。

      合理的做法是:设立一个输入缓存区,用以接受用户输入的一行字符,然后

    逐行存入用户数据区,并假设“#” 为退格符,“@” 为退行符。假设从终端接受了这

    样两行字符:

          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结束输入,#退格,@清空当前行:
    ");
    15     ch = getchar();  //从终端接受第一个字符
    16     while (ch != EOF)  //EOF为ctrl+z,全文结束符
    17     {
    18         while (ch != EOF && ch != '
    ')  //行结束或全文结束
    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('
    ', 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("建立文件失败!
    ");
    59     
    60     return 0;
    61 
    62 }
  • 相关阅读:
    第六节:流上下文
    第五节:控制序列化和反序列化的数据
    第四节:格式化器如何序列化类型实例
    第三节:控制序列化和反序列化
    第二节:使类型可序列化
    第一节:序列化和反序列化快速入门
    第五节:使用反射发现类型成员
    golang 一些坑 rang
    golang json格式字符串反序列化映射到切片结构体
    golang 结构体内嵌结构体序列化填充
  • 原文地址:https://www.cnblogs.com/mwq1024/p/10241613.html
Copyright © 2011-2022 走看看