全屏幕编辑软件的编写(C语言)01

浩淇宝宝

浩淇宝宝

2016-02-19 13:26

get新技能是需要付出行动的,即使看得再多也还是要动手试一试。今天图老师小编跟大家分享的是全屏幕编辑软件的编写(C语言)01,一起来学习了解下吧!

这是一个DOS下的全屏幕编辑软件,整个程序功能齐全,但代码并不多,可以制表格,打印、搜索、块复制,有点类似DOS下的WPS。这个程序作为学习C语言编程的参考是很好的,假如能够仔细阅读该程序,并加以理解,那么你的编程能力会有很大提高。

/* 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;                   /* 读入的外部文件和字块写盘的文件指针 */

(本文来源于图老师网站,更多请访问https://m.tulaoshi.com/bianchengyuyan/)

main(int argc,char *argv[])      /* 主控函数 */
{
  int i;
  clss(0,HH);                    /* 清全部屏幕 */
  mod();                         /* 测显示模式 */
  for(i=0;iQB;i++) {            /* 为给编辑数组分配内存建的循环 */
    ss[i]=malloc(HC);            /* 逐行分配内存空间 */
    *ss[i]=0;                    /* 数组行清为空串 */
  }
  mfile=malloc(16);              /* 为编辑文件名字符串分配内存空间 */
  *mfile=0;                      /* 字符串清为空串 */
  if(argc1)  mfile=argv[1];     /* 如进入 BJ 时带命令行参数,放入 mfile */
  filename();                    /* 输入文件名,建临时文件名,老文件读入 */
  hsz=malloc(HC);                /* 为指针变量 hsz 分配内存空间 */
  fnd=malloc(HC);                /* 为搜索字符串变量分配内存空间 */
  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;i8;i++)  {                         /* 显示一块彩色 */
    write_space(i,2,23,0x10);                 /* 蓝底色 */
    if(i!=1) write_string(i,25,"  ",0x30);    /* 右部浅蓝色影子 */
  }
  for(i=4;i27;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 && page1)  page--;    /* 如按 PgUP,如不在首页,显示上页目录 */
      if(k==-5 && pagetatol) page++; /* 按 PgDn,如不在最后页,显示下页目录*/
    }
  }
  clss(0,HH);                         /* 清全部屏幕 */
  for(i=0;iQB;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_rdQ2-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;k80;k++)
    write_char(14,k,'_',TEXT_COLOR); /* 在屏幕第 14 行画一横线,区分目录区 */
  clss(15,HH);                       /* 清目录显示区 */
  k=(a-1)*PG;                        /* 根据页号确定数组显示的起始项 */
  while(ka*PG)  {                   /* 为显示一页建的循环 */
    write_string(i,j,ss[k++],0x0E);  /* 显示一个文件名 */
    j+=13;                           /* 右移 13 列 */
    if(j67)  {                      /* 如列号大于 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 字符串以 '' 结尾 */
  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;ia+b;i++) {                     /* 为逐行读出设的循环 */
    if(fgets(ss[i],HC,f)==NULL) {          /* 从 f 读出一行,如已超出文末 */
      j=0;                                 /* j 置初值 */
      while(ss[i-1][j]) {                  /* 检查文末行各字节 */
        if(ss[i-1][j]==0x1A) {             /* 文件结束符用 '' 替代 */
          ss[i-1][j]=0;
          break;
        }
        j++;                               /* 下移一字节 */
      }
      break;                               /* 跳出 for 循环 */
    }
  }
  clear_prompt();                          /* 清提示区 */
  return i-a;                              /* 返回读出行数 */
}

(本文来源于图老师网站,更多请访问https://m.tulaoshi.com/bianchengyuyan/)

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

展开更多 50%)
分享

猜你喜欢

全屏幕编辑软件的编写(C语言)01

编程语言 网络编程
全屏幕编辑软件的编写(C语言)01

全屏幕编辑软件的编写(C语言)03

编程语言 网络编程
全屏幕编辑软件的编写(C语言)03

s8lol主宰符文怎么配

英雄联盟 网络游戏
s8lol主宰符文怎么配

全屏幕编辑软件的编写(C语言)05

编程语言 网络编程
全屏幕编辑软件的编写(C语言)05

全屏幕编辑软件的编写(C语言)06

编程语言 网络编程
全屏幕编辑软件的编写(C语言)06

lol偷钱流符文搭配推荐

英雄联盟 网络游戏
lol偷钱流符文搭配推荐

全屏幕编辑软件的编写(C语言)04

编程语言 网络编程
全屏幕编辑软件的编写(C语言)04

全屏幕编辑软件的编写(C语言)02

编程语言 网络编程
全屏幕编辑软件的编写(C语言)02

lolAD刺客新符文搭配推荐

英雄联盟
lolAD刺客新符文搭配推荐

APPLET实例-从源代码到应用

APPLET实例-从源代码到应用

利用管道进行进程的通信示例

利用管道进行进程的通信示例
下拉加载更多内容 ↓