当前位置:网站首页>>电脑技术>>C、C++语言>>我的著作 双击自动滚屏
中西文全屏幕编辑程序的设计和编制(九)

发表日期:2006年1月1日      已经有5067位读者读过此文

                  附录   BJ 中西文全屏幕编辑软件源程序清单

/* BJ.C 全屏幕编辑软件 (Turbo_C 2.0) */
/* 用  tcc -mc bj  编译 */
#include "stdio.h"
#include "dir.h"
#include "dos.h"
#include "ctype.h"
#include "alloc.h"

#define BLCK_COLOR 0x1E      /* 字块色彩 */
#define TEXT_COLOR 0x02      /* 文本字符色彩 */
#define PROM_COLOR 0x5F      /* 提示及提问行色彩 */
#define CHAR_COLOR 0x03      /* 行末示意符色彩 */
#define HH 24                /* 屏幕最大行坐标 */
#define H1 (HH-1)            /* 序号、文件名信息行行坐标 */
#define H2 (HH-2)            /* 标尺行行坐标 */
#define H3 (HH-3)            /* 编辑文本显示最下行行坐标 */
#define ZS 76                /* 每行显示文本的字数 */
#define BP (ZS/2)            /* 每次移屏字节数 */
#define FH (ZS+3)            /* 行末示意符列坐标 */
#define QB 400               /* 编辑数组可容纳的总行数 */
#define Q1 (QB/2)            /* 编辑数组中间值 */
#define Q2 (QB*3/5)          /* 第一次读入编辑数组的行数 */
#define Q3 (QB*2/5)          /* 每次读写临时文件的行数 */
#define SZ 1000              /* 临时文件每次读写地址数组最大下标 */
#define HC 255               /* 编辑数组每行最大字节数控制值 */
#define KK 32000             /* 字块允许的最大字节数 */
#define PG ((HH-16)*6)       /* 显示文件目录时,每页可显示目录数 */
long xx=0;                   /* 当前行在文本中的绝对行号 */
int yy=0;                    /* 当前列的文本列号,也是编辑数组列号 */
int ss_max=0;                /* 编辑数组实用最大行号 */
int x=0,y=0;                 /* 当前行在显示屏幕上的行、列坐标 */
int ss_x=0;                  /* 当前行在编辑数组中的行号 */
int m=0;                     /* 左右移屏屏号,首屏为 0 */
int fp_end=0;                /* 老文件是否读完的标志变量 */
int old=1;                   /* 区别新、老文件的标志变量 */
int ins=0;                   /* 是否为插入状态的标志变量 */
int vid=0;                   /* 区别图形和字符显示方式的标志变量 */
int tab=0;                   /* 中文表格线开关变量 */
int blck=0;                  /* 是否已定义字块的标志变量 */
int enq=HC-4;                /* 排版行宽,初值设为 HC-4 */
long ksx=-1;                 /* 块首行号,未定义块时置 -1 */
int ksy=-1;                  /* 块首列号,未定义块时置 -1 */
long kwx=-1;                 /* 块尾行号,未定义块时置 -1 */
int kwy=-1;                  /* 块尾列号,未定义块时置 -1 */
long txx,tyy;                /* 字块操作时保存原 xx,yy 坐标的变量 */
int chg=0;                   /* 文件是否已修改过的标志变量 */
int first=0;                 /* 字块中首行长度字节数 */
int oa=0,ob=0;               /* 数组 wra[ ] 和 wrb[ ] 的标号变量 */
long wra[SZ],wrb[SZ];        /* 记录临时文件读写地址的数组 */
long fp_rd;                  /* fp_rd 为 fp 已读出行的最大行号 */
long ttl_x=0xFFFFFFFL;       /* 文末行行号,先设一大数,fp 全部读完后,
                                  用已读出行最大行号 fp_rd 代替 */
long ser=0;                  /* 当前光标处的字序数 */
long vw=0;                   /* 临时存盘时,保存正文文件读指针的变量 */
long vv=0;                   /* 读块时,存放读入块的字节数 */
unsigned char z1,z2,a1,a2;   /* 为判断标点符号设置的变量 */
unsigned char *ss[QB];       /* 编辑缓冲区数组(简称编辑数组) */
char *mfile,*bfile;          /* 分别存放源文件名和后备文件名 */
char *file1,*file2;          /* 分别存放临时文件 1、2 的文件名 */
char far *mem, far *mmm;     /* 长城字符方式显存基本区和扩展区地址指针 */
char *ddd,*dd;               /* ddd 为读入块的指针变量,dd 为保存ddd串首的指针 */
char *hsz;                   /* 提问时输入字符串的指针变量 */
char *fnd;                   /* 存放要搜索的字符串 */
char two;                    /* 存放全角制表符第二字节的字符变量 */
char qq;                     /* 全角制表符第二字节的标志变量 */
char da[]={0x0D,0x0A,0};     /* 只有硬回车换行符的字符串 */
char ra[]={0x8D,0x0A,0};     /* 只有软回车换行符的字符串 */
struct ffblk pt[1];          /* 读文件目录用的结构 */
union REGS r;                /* 中断调用函数用的联合 */
union inkey  {               /* 存放按键值的联合 */
  unsigned char ch[2];       /* ch[0] 为高位字节, ch[1] 为低位字节 */
  int ii;
} cc;
FILE *fp,*fopen();           /* fp 为老文件 mfile 的文件指针 */
FILE *fp1,*fp2;              /* 临时文件 1、2 的文件指针 */
FILE *fp3;                   /* 读入的外部文件和字块写盘的文件指针 */

main(int argc,char *argv[])      /* 主控函数 */
{
  int i;
  clss(0,HH);                    /* 清全部屏幕 */
  mod();                         /* 测显示模式 */
  for(i=0;i<QB;i++) {            /* 为给编辑数组分配内存建的循环 */
    ss[i]=malloc(HC);            /* 逐行分配内存空间 */
    *ss[i]=0;                    /* 数组行清为空串 */
  }
  mfile=malloc(16);              /* 为编辑文件名字符串分配内存空间 */
  *mfile=0;                      /* 字符串清为空串 */
  if(argc>1)  mfile=argv[1];     /* 如进入 BJ 时带命令行参数,放入 mfile */
  filename();                    /* 输入文件名,建临时文件名,老文件读入 */
  hsz=malloc(HC);                /* 为指针变量 hsz 分配内存空间 */
  fnd=malloc(60);                /* 为搜索字符串变量分配内存空间 */
  disp_t();                      /* 显示编辑屏幕 */
  Ins();                         /* 置初始状态为“插入”状态 */
  while(1) {                     /* 编辑主循环 */
    xh();                        /* 在信息行显示当前行、列、序号 */
    coord();                     /* 在标尺行显示标尺 */
    goto_xy(x,y);                /* 定屏幕文本光标位置 */
    cc.ii=bioskey(0);            /* 将按键值读入一联合中 */
    clear_prompt();              /* 清提示区 */
    if(cc.ch[0])  {              /* 如果低位字节不为 0 */
      switch(cc.ch[0]) {         /* 判断低位字节 */
        case 13:  Enter();       /* 如为回车键,输入回车键操作 */
                  break;         /* 跳出开关语句 */
        case 8:   Del();         /* 如为退格键,删字操作 */
                  break;         /* 跳出开关语句 */
        case 14:  Ctrl_N();      /* Ctrl+N 在当前行前插入一空行 */
                  break;         /* 跳出开关语句 */
        case 25:  Ctrl_Y(1);     /* Ctrl+Y 删除当前行 */
                  break;         /* 跳出开关语句 */
        case 20:  Ctrl_T(1);     /* Ctrl+T 删至行尾 */
                  break;         /* 跳出开关语句 */
        case 5:   Ctrl_E(1);     /* Ctrl+E 删至行首 */
                  break;         /* 跳出开关语句 */
        case 6:   Ctrl_F(1);     /* Ctrl+F 移至块首 */
                  break;         /* 跳出开关语句 */
        case 22:  Ctrl_V();      /* Ctrl+V 字块移动 */
                  break;         /* 跳出开关语句 */
        case 11:  Ctrl_K();      /* Ctrl+K 字块拷贝 */
                  break;         /* 跳出开关语句 */
        case 23:  Ctrl_W();      /* Ctrl+W 字块存盘 */
                  break;         /* 跳出开关语句 */
        case 4:   Ctrl_D();      /* Ctrl+D 删除字块 */
                  break;         /* 跳出开关语句 */
        case 16:  Ctrl_P();      /* Ctrl+P 打印当前编辑的文本文件 */
                  break;         /* 跳出开关语句 */
        case 18:  Ctrl_R();      /* Ctrl+R 外部文件插入当前位置 */
                  break;         /* 跳出开关语句 */
        case 27:  Esc();         /* Esc 键 不存盘退出 */
                  break;         /* 跳出开关语句 */
        case 3:   bk();          /* Ctrl+C 退回 DOS 系统 */
        default:  Chr();         /* 如为字符键,输入字符 */
      }
    }
    else   {                     /* 如果低位字节为 0 */
      switch(cc.ch[1])  {        /* 判断高位字节 */
        case 81:  PgDn();        /* PgDn 键,向下翻屏 */
                  break;         /* 跳出开关语句 */
        case 73:  PgUp();        /* PgUp 键,向上翻屏 */
                  break;         /* 跳出开关语句 */
        case 59:  F1(1);         /* F1 存盘并退出 */
                  break;         /* 跳出开关语句 */
        case 84:  Shift_F1();    /* Shift+F1,存盘,不退出 */
                  break;         /* 跳出开关语句 */
        case 60:  F2();          /* F2 移到指定行 */
                  break;         /* 跳出开关语句 */
        case 61:  F3();          /* F3 输入格式文件排版行宽 */
                  break;         /* 跳出开关语句 */
        case 62:  F4();          /* F4 段排版 */
                  break;         /* 跳出开关语句 */
        case 87:  Shift_F4();    /* Shift+F4 从当前光标行排版至文末 */
                  break;         /* 跳出开关语句 */
        case 63:  F5();          /* F5 搜索字符串 */
                  break;         /* 跳出开关语句 */
        case 88:  Shift_F5();    /* Shift+F5 继续搜索 */
                  break;         /* 跳出开关语句 */
        case 64:  F6();          /* F6 字符串的替代 */
                  break;         /* 跳出开关语句 */    
        case 65:  F7();          /* F7 定义块首 */
                  break;         /* 跳出开关语句 */
        case 66:  F8();          /* F8 定义块尾 */
                  break;         /* 跳出开关语句 */
        case 90:                 /* Shift+F7 */
        case 91:  Shift_F7();    /* Shift+F8 取消块定义 */
                  break;         /* 跳出开关语句 */
        case 67:  F9();          /* F9 光标移到文首 */
                  break;         /* 跳出开关语句 */
        case 92:  Shift_F9();    /* Shift+F9 光标移到文末 */
                  break;         /* 跳出开关语句 */
        case 68:  F10();         /* F10 表格线功能开关 */
                  break;         /* 跳出开关语句 */
        case 77:  Right();       /* → 键 右移光标 */
                  break;         /* 跳出开关语句 */
        case 75:  Left();        /* ← 键 左移光标 */
                  break;         /* 跳出开关语句 */
        case 72:  Up();          /* ↑ 键 上移一行 */
                  break;         /* 跳出开关语句 */
        case 80:  Down();        /* ↓ 键 下移一行 */
                  break;         /* 跳出开关语句 */
        case 82:  Ins();         /* Ins 插入状态转换 */
                  break;         /* 跳出开关语句 */
        case 83:  Del();         /* Del 同退格键 */
                  break;         /* 跳出开关语句 */
        case 71:  Home();        /* Home 光标移到行首 */
                  break;         /* 跳出开关语句 */
        case 79:  End();         /* End 光标移到行末 */
                  break;         /* 跳出开关语句 */
      }
    }
  }
}

mark()                                        /* 软件标志 */
{
  int i;
  for(i=1;i<8;i++)  {                         /* 显示一块彩色 */
    write_space(i,2,23,0x10);                 /* 蓝底色 */
    if(i!=1) write_string(i,25,"  ",0x30);    /* 右部浅蓝色影子 */
  }
  for(i=4;i<27;i++)  write_char(8,i,32,0x30); /* 下部浅蓝色影子 */
  write_string(3,6,"BJ全屏幕编辑工具",0x1E);  /* 显示软件名称 */
  write_string(4,10,"Ver1.0",0x1E);           /* 显示版本号 */
  write_string(5,9,"沈 建 威",0x1E);          /* 显示设计者姓名 */
}

filename()                            /* 输入要编辑的文件名 */
{
  int i,k,tatol,page=1;               /* tatol 目录总页数, page 目录显示页号 */
  if(!*mfile) {                       /* 如未带命令行参数,mfile 为空串 */
    mark();                           /* 显示软件标志 */
    write_string(11,20,"请输入要编辑的文件名:",0x0A);
    tatol=make_dir();                 /* 建目录数组,总页数放入 tatol */
    while(1)  {                       /* 为目录翻屏设置的循环 */
      disp_dir(page);                 /* 显示目录清单 */
      write_space(11,42,20,0x0A);     /* 用 20 个空格清文件名输入区屏幕 */
      if((k=key_string(11,42,mfile,0x0A))>0) break;/* 输入文件名,成功跳出循环*/
      if(k==-1 || k==0)  bk();        /* 如为空串或按 ESC 退出至 DOS 下 */
      if(k==-4 && page>1)  page--;    /* 如按 PgUP,如不在首页,显示上页目录 */
      if(k==-5 && page<tatol) page++; /* 按 PgDn,如不在最后页,显示下页目录*/
    }
  }
  clss(0,HH);                         /* 清全部屏幕 */
  for(i=0;i<QB;i++)  *ss[i]=0;        /* 清编辑数组 */
  if((fp=fopen(mfile,"rb"))==NULL) {  /* 用只读方式打开文件,如失败为新文件 */
    old=0;                            /* old=0 为新文件 */
    fp_rd=0;                          /* 已从 fp 中读入行最大行号置为 0 */
    write_string(H1,40,"新",0x05);    /* 在信息行提示新文件 */
  }
  else  fp_rd=read_from(0,Q2,fp)-1;   /* 如为老文件,读 Q2 行到编辑数组 */
  write_string(H1,42,"文件名:",0x05); /* 在信息行提示 */
  write_string(H1,50,mfile,0x07);     /* 在信息行显示文件名 */
  if(fp_rd<Q2-1) {                    /* 如读入不足 Q2 行, fp 已读完 */
    ttl_x=fp_rd;                      /* 定文末总行号 */
    fp_end=1;                         /* fp 已读完标志置 1 */
  }
  ss_max=fp_rd;                       /* 定编辑数组实用最大行号 */
  f_name();                           /* 建辅助文件名 */
}

int make_dir()                        /* 找当前目录中合适的文件名记入数组 */
{
  int i=0;
  if(findfirst("*.*",pt,0)==0 && compare())    /* 寻找第一个文件名并比较 */
    strcpy(ss[i++],pt[0].ff_name);    /* 如不是要忽略的文件,将它赋给数组 */
  while(findnext(pt)==0)  {           /* 为继续找文件设的循环 */
    if(compare())                     /* 比较找到的文件名 */
      strcpy(ss[i++],pt[0].ff_name);  /* 如比较为真,记入数组 */
  }
  return (i-1)/PG+1;                  /* 返回可供显示页数 */
}

int compare()        /* 如扩展名为 EXE 等可忽略的文件名,返回 0,否则返回 1 */
{
  if(strstr(pt[0].ff_name,".EXE") || strstr(pt[0].ff_name,".COM")
           || strstr(pt[0].ff_name,".OV") || strstr(pt[0].ff_name,".OBJ")
           || strstr(pt[0].ff_name,".LIB") || strstr(pt[0].ff_name,".BAK")
           || strstr(pt[0].ff_name,".FOX") || strstr(pt[0].ff_name,".DBF")
           || strstr(pt[0].ff_name,".IDX"))
    return 0;
  return 1;
}

disp_dir(int a)                      /* 显示目录,a 为页号 */
{
  int i=16,j=1,k;                    /* i 为行坐标,j 为列坐标 */
  for(k=0;k<80;k++)
    write_char(14,k,''_'',TEXT_COLOR); /* 在屏幕第 14 行画一横线,区分目录区 */
  clss(15,HH);                       /* 清目录显示区 */
  k=(a-1)*PG;                        /* 根据页号确定数组显示的起始项 */
  while(k<a*PG)  {                   /* 为显示一页建的循环 */
    write_string(i,j,ss[k++],0x0E);  /* 显示一个文件名 */
    j+=13;                           /* 右移 13 列 */
    if(j>67)  {                      /* 如列号大于 67 */
      ++i;                           /* 下移一行 */
      j=1;                           /* 列号置 1 */
    }
  }
}

f_name()                             /* 建临时文件和后备文件名 */
{
  int i;
  bfile=malloc(16);                  /* 为后备文件名字符串分配内存空间 */
  file1=malloc(16);                  /* 为临时文件名字符串分配内存空间 */
  file2=malloc(16);                  /* 为临时文件名字符串分配内存空间 */
  for(i=0;*(mfile+i)!=''.'' && *(mfile+i);i++)  *(bfile+i)=*(mfile+i);
                                     /* 截取文件名“.”前的部分,放入 bfile */
  *(bfile+i)=0;                      /* bfile 字符串以 ''\0'' 结尾 */
  strcpy(file1,bfile);               /* bfile 中字符串拷入 file1 */
  strcpy(file2,bfile);               /* bfile 中字符串拷入 file2 */
  strcat(bfile,".BAK");              /* bfile 加后缀.BAK */
  strcat(file1,".$1$");              /* 临时文件 1 加后缀.$1$ */
  strcat(file2,".$2$");              /* 临时文件 2 加后缀.$2$ */
  fp1=fopen(file1,"wb+");            /* 打开临时文件 1 */
  fp2=fopen(file2,"wb+");            /* 打开临时文件 2 */
}

bk()                                 /* 退出运行,至 DOS 下 */
{
  fcloseall();                       /* 关闭所有打开的文件 */
  remove(file1);                     /* 删除临时文件 1 */
  remove(file2);                     /* 删除临时文件 2 */
  clss(0,HH);                        /* 清屏 */
  goto_xy(0,0);                      /* 光标置屏幕左上角 */
  exit(0);                           /* 退出运行 */
}

write_prompt(char a)            /* 在屏幕提示区显示提示,a 为提示项数组下标 */
{
  char *prom[]=  {                         /* 存放提示的数组 */
    "请稍候.....",
    "请先定义块!",
    "块太大!",
    "行宽超过250!",
    "必须输入数字!",
    "只允许输入 Y 或 N!",
    "文件未找到!",
    "排版超宽!",
    "未设定排版宽度!"
  };
  int g;
  g=80-strlen(prom[a]);                    /* 显示起始列 */
  if(a)  putchar(7);                       /* 除第一项提示外,其余各项响铃警告 */
  write_string(HH,g,prom[a],PROM_COLOR);   /* 在提示区显示提示 */
}

write_ques(char a)           /* 在屏幕提问区显示提问,a 为提问项数组下标 */
{
  char *ques[]=  {                         /* 存放提问的数组 */
    "是否放弃并退出编辑?(Y/N)    ",
    "请输入字块存盘的文件名:                  ",
    "已有同名文件,是否复盖?(Y/N)    ",
    "请输入要插入的文件名:                  ",
    "请输入排版行宽:       ",
    "请输入要找的字符串:                                ",
    "请输入要移到的行号:         ",
    "寻找:                     换成:                      换否?  ",
    "请输入每页打印的行数:      ",
    "打印机未准备好,请准备好打印机,按任一键继续。",
    "请调好打印纸,按任一键开始打印。",
    "正在打印.....",
    "请输入页号打印列号:       ",
    "请输入起始页号:       "
  };
  clear_ques();                            /* 清提问区 */
  write_string(HH,0,ques[a],PROM_COLOR);   /* 在提问区显示提问 */
}

clear_prompt()                             /* 清提示区 */
{
  write_space(HH,60,20,TEXT_COLOR);        /* 用空格复盖提示区 */
}

clear_ques()                               /* 清提问区 */
{
  write_space(HH,0,60,TEXT_COLOR);         /* 用空格复盖提问区 */
}

int read_from(int a,int b,FILE *f)  /* 从文件 f 读入 b 行放入数组的第 a 行起 */
{
  int i,j;
  write_prompt(0);                         /* 提示“请稍候...” */
  for(i=a;i<a+b;i++) {                     /* 为逐行读出设的循环 */
    if(fgets(ss[i],HC,f)==NULL) {          /* 从 f 读出一行,如已超出文末 */
      j=0;                                 /* j 置初值 */
      while(ss[i-1][j]) {                  /* 检查文末行各字节 */
        if(ss[i-1][j]==0x1A) {             /* 文件结束符用 ''\0'' 替代 */
          ss[i-1][j]=0;
          break;
        }
        j++;                               /* 下移一字节 */
      }
      break;                               /* 跳出 for 循环 */
    }
  }
  clear_prompt();                          /* 清提示区 */
  return i-a;                              /* 返回读出行数 */
}

write_to(int a,int b,FILE *f)        /* 把编辑数组第 a 行起的 b 行写入文件 f */
{
  int i;
  write_prompt(0);                         /* 提示“请稍候...” */
  for(i=a;i<a+b;i++) fputs(ss[i],f);       /* 逐行将字符串写入文件 f */
  clear_prompt();                          /* 清提示区 */
}

coord()                                    /* 显示标尺行 */
{
  int i,j,k,g;
  g=m*BP;                                  /* 本屏行首列号 */
  y=yy-g;                                  /* 计算 y */
  k=(enq-g>ZS+1)?ZS+1:enq-g;               /* 排版宽度处列坐标 */
  for(i=1;i<=ZS+1;i++)  {                  /* 自左至右显示标尺 */
    j=(i<=k)?0x04:0x01;                    /* 排版行宽度内用红色,否则用蓝色 */
    ((i+g)%5==0)?write_char(H2,i-1,''|'',j):write_char(H2,i-1,''-'',j);
                                           /* 逢 5 显示“|”,其余显示“-” */
  }
  g=(y<k) ? 0x50 : 0x30;                   /* 确定标尺光标色彩 */
  ((yy+1)%5==0)?write_char(H2,y,''|'',g):write_char(H2,y,''-'',g);
                                           /* 显示标尺光标 */
}

xh()                                   /* 在信息行显示当前行序、列、行数值 */
{
  char sl[8],sh[8],sz[8];
  itoa(yy+1,sl,10);                        /* 变列号数值为字符串 */
  ltoa(xx+1,sh,10);                        /* 变行号数值为字符串 */
  ltoa(ser+1,sz,10);                       /* 变字序号数值为字符串 */
  write_string(H1,8,"序:         行:        列:    ",0x05);
  write_string(H1,12,sz,0x07);             /* 显示字序号 */
  write_string(H1,24,sh,0x07);             /* 显示行号 */
  write_string(H1,35,sl,0x07);             /* 显示列号 */
}

int string_lingth()                        /* 计算除回车换行符外的当前行长 */
{
  int g;
  g=strlen(ss[ss_x]);                      /* 测当前行字符串总长 */
  if(ss[ss_x][g-1]==0x0A) g-=2;            /* 去除回车换行符的长度 */
  return g;                                /* 返回计算值 */
}

Enter()                                    /* 输入回车 */
{
  int g,k;
  chg=1;                                   /* 文件已修改标志置为真 */
  if(!ins) {                               /* 如为非插入状态 */
    g=string_lingth();                     /* 计算当前行长(不包括回车换行符) */
    strcpy(ss[ss_x]+g,da);                 /* 字符串以硬回车换行符结尾 */
    if(xx==ttl_x)   {                      /* 如是文末行,下移一行 */
      fp_rd++;                             /* fp 已读出行最大行号加 1 */
      ttl_x++;                             /* 文末行行号加 1 */
      ss_max++;                            /* 编辑数组实用最大行号加 1 */
    }
    if(m==0 && g<ZS)  write_char(x,FH,''<'',CHAR_COLOR);
                                           /* 如行尾在 0 屏,显示硬回车标志 */
    ss_x++;   xx++;                        /* 数组行号和文本行号均加 1 */
    ser+=g-yy+2;                           /* 计算字序数 */
    if(ss_x>ss_max)  tj();                 /* 如下行超出编辑数组最大行号,
                                              从 fp2 或 fp 读入一部分 */
    if(x<H3)  {                            /* 如不是屏幕底行 */
      if(m)  {                             /* 如不是 0 屏 */
        m=0;
        disp_t();                          /* 显示 0 屏各行 */
      }
      x++;                                 /* 屏幕光标下移一行 */
    }
    else  {                                /* 如是屏幕最下行 */
      if(!m) {                             /* 如原在 0 屏,则滚屏 */
        roll_scr_up(0,H3);                 /* 向上滚屏 */
        disp(ss_x,x);                      /* 当前坐标补显一行 */
      }
      else  {                              /* 如原不在 0 屏 */
        m=0;                               /* 显示 0 屏 */
        disp_t();
      }
    }
  }
  else  {                                  /* 如为插入状态 */
    g=m;                                   /* 保存原屏号 */
    k=x;                                   /* 保存原屏幕行坐标 */
    intercept(yy);                         /* 从当前光标处折断字符串 */
    strcpy(ss[ss_x-1]+yy,da);              /* 折断处加硬回车换行符 */
    if(!g) {                               /* 如原在 0 屏 */
      if(k<H3)  roll_scr_down(x,H3);       /* 不在屏底行,本行起下滚 */
      else   roll_scr_up(0,H3);            /* 在屏底行,全屏上滚 */
      disp(ss_x-1,x-1);                    /* 重显原行(上一行) */
      disp(ss_x,x);                        /* 显示当前行 */
    }
    else  disp_t();                        /* 如原不在 0 屏,重显一屏 */
  }
  yy=0;                                    /* 光标至行首 */ 
}

Del()                                      /* 退格键、删字键处理 */
{
  int i,k;
  k=x;                                     /* 保存原行坐标 */
  chg=1;                                   /* 文件已修改标志置为真 */
  switch(delc()) {                         /* 删字,根据返回值判断 */
    case 0:                                /* 如返回 0 */
      disp(ss_x,x);                        /* 重显当前行 */
      break;                               /* 跳出开关语句 */
    case 1:                                /* 如返回 1 */
      disp_t();                            /* 重显一屏 */
      break;                               /* 跳出开关语句 */
    case 2:                                /* 如返回 2 */
      if(x>0)  --x;                        /* 如不在屏幕最上行,光标上移一行 */
      comput();                            /* 计算参数 */
      if(m) disp_t();                      /* 如不在 0 屏,重显一屏 */
      else  {                              /* 如在 0 屏 */
        if(k) {                            /* 如原不在屏顶行 */
          roll_scr_up(k,H3);               /* 自当前行起滚屏 */
          i=H3-x;                          /* 屏幕最下行与当前行间行数 */
          if(xx+i<=ttl_x)                  /* 如最下行还有,显示此行 */
            disp(ss_x+i,H3);
        }
        disp(ss_x,x);                      /* 显示当前行 */
      }
      break;                               /* 跳出开关语句 */
  }
}

int delc()                          /* 删字,如在行首,将本行接在上行尾 */
{
  int i,g,k=0;
  for(;;)  {                        /* 为全角字符设的循环 */
    if(y>0)  {                      /* 如不在本屏行首 */
      if(xx==ksx && yy<=ksy) ksy--; /* 如在块首行,并在块首前,计算块首列号 */
      if(xx==kwx && yy<=kwy) kwy--; /* 如在块尾行,并在块尾前,计算块尾列号 */
      dks();                        /* 如块首、块尾重合, 块标志置 1 */
      strcpy(ss[ss_x]+yy-1,ss[ss_x]+yy);
                                /* 光标处起字符串前移一格,覆盖光标前一字符 */
      y--;    yy--;                 /* 前移一字节 */
      ser--;                        /* 字序号减 1 */
      if(vs(yy-1)==0)  {            /* 如不在全角前半字 */
        if(!k) return 0;            /* 如在屏幕最左列,返回 0 */
        else return 1;              /* 否则返回 1 */
      }
    }
    else  {                         /* 如在屏幕最左列 */
      if(m)  {                      /* 如不为 0 屏 */
        m--;                        /* 退到前一屏 */
        y=yy-m*BP;                  /* 光标到屏中,并前移一字 */
        k=1;                        /* 标志置 1 */
      }
      else  {                       /* 如为 0 屏 */
        if(ss_x+(i=H3-x)>=ss_max && xx+i<ttl_x)
          tj();      /* 如屏幕最下行超出数组,但未到文末,从fp2或fp读入Q3行 */
        if(xx)  {                   /* 如不在文首行 */
          g=strlen(ss[ss_x]);       /* 测行长 */
          ss_x--;                   /* 至上一行 */
          yy=string_lingth();       /* 定光标于上行尾处 */
          if(g+yy>HC-4)  {          /* 如两行相接后超长 */
            write_prompt(3);        /* 提示超长 */
            yy=0;                   /* 恢复原行列号 */
            ss_x++;                 /* 回原行 */
            return -1;              /* 退出,返回 -1 */
          }
          if(xx<=ksx)  {            /* 如在块首行或之前 */
            if(xx==ksx) ksy+=yy;    /* 如在块首行 */
            ksx--;                  /* 块首行行号减 1 */
          }
          if(xx<=kwx) {             /* 如在块尾行或之前 */
            if(xx==kwx) kwy+=yy;    /* 如在块尾行 */
            kwx--;                  /* 块尾行行号减 1 */
          }
          dks();                    /* 如块首、块尾重合, 块标志置 1 */
          xx--;                     /* 文本当前行改为上行 */
          strcpy(ss[ss_x]+yy,ss[ss_x+1]);   /* 将下行拷至本行尾回车符前 */
          ser-=2;                   /* 字序数减少回车符的两位 */
          movbk(ss_x+1,1);          /* 数组后续各行前移,覆盖原行 */
          ttl_x--;                  /* 文末行行号减 1 */
          fp_rd--;                  /* fp 已读出行最大行号减 1 */
          ss_max--;                 /* 数组实用最大行号减 1 */
          return 2;                 /* 返回 2 */
        }
        else return 0;              /* 如在文首行,返回 0 */
      }
    }
  }
}

int vs(int a)                       /* 计算行首至 a 列全角字节数,返回奇偶值 */
{
  int i,j;
  j=0;                              /* 全角字节数,初值为 0 */
  for(i=0;i<=a;i++)
    if(ss[ss_x][i]>0xA0) j++;       /* 统计全角字节数 */
  return(j%2);                      /* 返回奇偶值 */
}

orien()                             /* 重定光标列号 */
{
  int g;
  g=string_lingth();                /* 测当前列长(不包括回车换行符) */
  if(yy>g)  yy=g;                   /* 如光标在字符串尾后,定光标于串尾 */
  if(vs(yy-1))  yy--;               /* 如光标在后半汉字,前移一字节 */
  y=yy-m*BP;                        /* 计算屏幕 y 坐标 */
  if(y<0) comput();                 /* 如 y 为负数,重算各参数 */
}

Ctrl_N()                            /* 插入一空行 */
{
  chg=1;                            /* 文件已修改标志置为真 */
  fp_rd++;                          /* fp 已读出最大行号加 1 */
  ttl_x++;                          /* 文末行行号加 1 */
  if(xx<=ksx)  {                    /* 如插入行在块首行或之前 */
    ksx++;    kwx++;                /* 块首、块尾行号加 1 */
  }
  else {                            /* 如插入行在块首行后 */
    if(xx>ksx && xx<=kwx) kwx++;    /* 如插入行在字块中,块尾行号加 1 */
  }
  ser-=yy;                          /* 计算字序数 */
  if(ss_max>=QB-1) {                /* 如超出缓冲区数组可容行数 */
     ss_x>Q1 ? wfp1() : wfp2();     /* 数组行数在 Q1 后时,上部 Q3 行存入 fp1,
                                     行数小于 Q1 时,下部 Q3 行存入 fp2 */
  }
  ss_max++;                         /* 编辑数组实用最大行号加 1 */
  mov(ss_x,1);                      /* 当前行起各行后移 */
  strcpy(ss[ss_x],da);              /* 插入行加硬回车换行符 */
  if(m)  {                          /* 如不在 0 屏,显示 0 屏 */
    m=0;
    disp_t();
  }
  else  roll_scr_down(x,H3);        /* 如在 0 屏,当前行以下各行下滚 */
  yy=0;                             /* 光标至行首 */
}

Ctrl_E(int a)                       /* 删至行首,a=1 显示,a=0 不显示 */
{
  int g;
  chg=1;                            /* 文件已修改标志置为真 */
  g=m;                              /* 保存原屏号 */
  if(xx==ksx)  {                    /* 如在块首行 */
    if(yy<=ksy)  ksy-=yy;           /* 如在块首前, 计算块首列号 */
    else  ksy=0;                    /* 如在块首后,块首列号置 0 */
  }
  if(xx==kwx)  {                    /* 如在块尾行 */
    if(yy<=kwy)  kwy-=yy;           /* 如在块尾前,计算块尾列号 */
    else  kwy=0;                    /* 如在块尾后,块尾列号置 0 */
  }
  dks();                            /* 如块首、块尾重合, 块标志置 1 */
  strcpy(ss[ss_x],ss[ss_x]+yy);     /* 光标后字符前移至行首起 */
  ser-=yy;                          /* 计算字序数 */
  m=0;                              /* 至 0 屏 */
  yy=0;                             /* 至行首 */
  if(a) {                           /* 如为按 Ctrl+E 键时,重显屏幕 */
    if(!g) disp(ss_x,x);            /* 如原在 0 屏,重显当前行 */
    else   disp_t();                /* 否则显示 0 屏 */
  }
}

Ctrl_Y(int a)                       /* 删行,a=1 显示,a=0 不显示 */
{
  int g,i;
  chg=1;                            /* 文件已修改标志置为真 */
  g=m;                              /* 保存原屏号 */
  if((ss_x+(i=H3-x))>=ss_max && xx+i<ttl_x)   tj();
                    /* 如屏幕最下行超出数组,但在总行数内,从fp2或fp读入Q3行 */
  if(xx<ksx) ksx--;                 /* 如被删行在块首行前,块首行号减 1 */
  else  if(xx==ksx) ksy=0;          /* 如被删行为块首行,块首列号置 0 */ 
  if(xx<kwx) kwx--;                 /* 如被删行在块尾行前,块尾行号减 1 */
  else  if(xx==kwx)  kwy=0;         /* 如被删行为块尾行,块尾列号置 0 */ 
  dks();                            /* 如块首、块尾重合,块标志 blck 置 1 */
  ser-=yy;                          /* 计算字序数 */
  if(xx<ttl_x) {                    /* 当删除最后一行时 */
    fp_rd--;                        /* fp 已读出最大行行号减 1 */
    ttl_x--;                        /* 文末行行号减 1 */
    ss_max--;                       /* 编辑数组实用最大行号减 1 */
  }
  movbk(ss_x,1);                    /* ss_x 后各行前移一行 */
  m=0;                              /* 至 0 屏 */
  yy=0;                             /* 至行首 */
  if(a) {                           /* 如参数 a 为真 */
    if(!g) {                        /* 如原在 0 屏 */
      roll_scr_up(x,H3);            /* 自当前行起滚屏 */
      if(xx+i<=ttl_x) disp(ss_x+i,H3);  /* 如最下行还有,显示此行 */
    }
    else  disp_t();                 /* 如原不在 0 屏,则显示 0 屏 */
  }
}


相关专题: 我的著作
专题信息:
  C语言速成(第三章 程序控制语句)(2006-1-1 13:51:28)[9515]
  C语言速成(第七章 联合、枚举和自定义数据类型)(2006-1-1 13:51:46)[10217]
  C语言速成(第六章 结构)(2006-1-1 13:52:05)[8907]
  C语言速成(第五章 指针)(2006-1-1 17:28:54)[4666]
  C语言速成(第四章 数组)(2006-1-1 13:52:42)[4811]

相关信息:
 没有相关信息
  打印本页
设为首页 | 加入收藏 | 联系我们 | 管理入口
皖ICP备05018956号
Copyright © 2003 J.W.SHEN All Rights Reserved
后台管理系统 V1.0 制作
皖公网安备 34018102340322号