/*文本编辑器editor源代码*/#includestdio.h#includeconio.h#includebios.h#includemath.h#defineLEFT0x4b00/*←:光标左移*/#defineRIGHT0x4d00/*→:光标右移*/#defineDOWN0x5000/*↓键:光标下移*/#defineUP0x4800/*↑键:光标上移*/#defineESC0x011b/*ESC键:取消菜单打开操作*/#defineENTER0x1c0d/*回车键:换行*/#defineDEL21248/*DEL键:删除当前字符*/#defineBACK3592/*BackSpace键:删除当前光标位置前一个字符*/#defineCL29440/*ctrl+←键:从右至左,选定文本*/#defineCR29696/*ctrl+→键:从左到右,选定文本*/#defineCc11779/*ctrl+c键:将选定文本,复制一份到剪贴板中*/#defineCv12054/*ctrl+v键:将剪贴板中的内容复制到当前位置*/#defineCx11544/*ctrl+x键:对选定文本,执行剪切操作*/#defineF115104/*F1键:打开文件菜单*/#defineF215360/*F2键:打开编辑菜单*/#defineF315616/*F3键:打开帮助菜单*/#defineF1017408/*F10键:进入文本快速预览模式*/intvalue,backup,NUM;/*value保存有值数组元素的最大下标值,backup保存value的副本,NUM保存当前行中的用户输入的字符个数*/typedefstructrecord{charch;/*保存一字符*/intcol,line;/*x轴和y轴坐标*/}record;recordr[500];/*定义一个有500个元素的结构体数组,保存选定的文本字符的属性*/typedefstructnode/*定义保存行中的单个字符的结构*/{charch;/*数据域:保存一字符*/structnode*next;/*指针域:指向下一个结点的指针*/}node;/*由此类型节点构成的单链表,命名为:列单链表*/typedefstructHnode/*定义保存所有列单链表首节点的指针的结构*/{node*next;/*指向列单链表的首节点的地址*/structHnode*nextl;/*指向下一个节点的指针*/}Hnode;/*由此类型节点构成的单链表,命名为:行单链表*/voiddrawmain()/*画主窗口函数*/{inti,j;gotoxy(1,1);/*在文本窗口中设置光标至(1,1)处*/textbackground(7);/*选择新的文本背景颜色,7为LIGHTGRAY淡灰色*/textcolor(0);/*在文本模式中选择新的字符颜色0为BLACK黑*/insline();/*在文本窗口的(1,1)位置处中插入一个空行*/for(i=1;i=24;i++){gotoxy(1,1+i);/*(x,y)中x不变,y++*/cprintf(%c,196);/*在窗口左边输出-,即画出主窗口的左边界*/gotoxy(80,1+i);cprintf(%c,196);/*在窗口右边,输出-,即画出主窗口的右边界*/}for(i=1;i=79;i++){gotoxy(1+i,2);/*在第2行,第2列开始*/cprintf(%c,196);/*在窗口顶端,输出-*/gotoxy(1+i,25);/*在第25行,第2列开始*/cprintf(%c,196);/*在窗口底端,输出-*/}gotoxy(1,1);cprintf(%c,196);/*在窗口左上角,输出-*/gotoxy(1,24);cprintf(%c,196);/*在窗口左下角,输出-*/gotoxy(80,1);cprintf(%c,196);/*在窗口右上角,输出-*/gotoxy(80,24);cprintf(%c,196);/*在窗口右下角,输出-*/gotoxy(7,1);cprintf(%c%cFile%c%c,179,17,16,179);/*||*/gotoxy(27,1);cprintf(%c%cEdit%c%c,179,17,16,179);/*||*/gotoxy(47,1);cprintf(%c%cHelp%c%c,179,17,16,179);/*||*/gotoxy(5,25);/*跳至窗口底端*/textcolor(1);cprintf(Row:1Col:1);gotoxy(68,25);cprintf(Version2.0);}voidqview(Hnode*q)/*快速预览文本:开头:#,回车:**/{voidview(Hnode*q);/*view()函数声明*/node*p;inti;window(1,1,80,25);/*定义文本窗口大小*/clrscr();/*清屏*//*循环读取两个单链表中的值:q是一个指向行单链表首节点的指针,此单链表数据域的值为实际保存各行字符的列单链表p中的首节点地址*/do{p=q-next;/*p指向保存行数据的列单链表的首节点的地址*/cprintf(#);/*每行开头,打印此字符,不管前面是否有回车符*/while(p!=NULL)/*循环读取单链表p中的值*/{if(p-ch==13)putch('*');/*若为回车键,打印出*号*/elseputch(p-ch);/*输出各行中的字符到预览窗口*/p=p-next;/*指向下一个节点*/}q=q-nextl;/*指向下一个节点*/printf(\n);/*输出一个回车*/}while(q!=NULL);getch();clrscr();drawmain();/*按任意键后,回到主窗口界面*/window(2,2,79,23);textbackground(9);for(i=0;i24;i++)insline();/*插入24个空行*/window(3,3,78,23);textcolor(10);}voidview(Hnode*q)/*按行显示保存在单链表中的文本字符,q为指向行单链表中第一个节点的指针*/{node*p;/*p为保存列单链表节点元素地址的指针*/clrscr();/*清屏*//*双重循环,读取并显示保存在单链表中字符*/do{p=q-next;while(p!=NULL&&p-ch=32&&p-ch127&&p-ch!=13&&p-ch!=-1)/*指针p不能为空,且数据域必须为常规字符*/{putch(p-ch);/*在文本窗口中输出该字符*/p=p-next;/*指向下一个节点*/}q=q-nextl;/*指向下一个节点*/if((p-ch==13||p-ch==-1)&&q!=NULL)gotoxy(1,wherey()+1);/*若ch为回车或EOF标记,光标跳至下行的开始处*/}while(q!=NULL);/*逐行逐列显示文本字符*/}intcheck(Hnode*Hhead,intm,intn)/*check():在单链表中检查第m行第n列位置的字符,若为常规字符,则返回该字符*/{inti;Hnode*q;node*p;q=Hhead;for(i=1;im;i++)/*定位至行单链表中的第m个元素*/q=q-nextl;p=q-next;/*获取第m个节点的数据域*/for(i=1;in;i++)/*定位至列单链表中的第n个元素*/p=p-next;if(p-ch==13)return-1;/*若第m行,第n列的字符为回车键,则返回-1*/if(p-ch=32&&p-ch127)returnp-ch;/*若第m行,第n列的字符为常规字符,则返回该字符*/elsereturn0;/*若第m行,第n列的字符既非回车符又非常规字符,则返回0*/}intjudge(Hnode*Hhead,intm)/*judge():返回第m行中的常规字符总的个数,不包括回车符*/{Hnode*q;node*p;inti,num=0;q=Hhead;for(i=1;im;i++)/*定位至行单链表中的第m个元素*/q=q-nextl;if(q==NULL)return-1;/*返回-1,表示第m行不存在*/p=q-next;while(p-next!=NULL){p=p-next;num++;/*统计第m行的字符个数*/}/*行尾字符还没有判断,接下来判断行尾字符*/if(p-ch==13&&num==0)return0;/*返回0,表示当前行只有一个回车字符*/if(p-ch=32&&p-ch127)returnnum+1;/*返回num+1,表示当前行的最后一个字符为常规字符*/if(p-ch==13&&num!=0)returnnum;/*返回num,表示当前行的最后一个字符为回车符,不计算在内*/elsereturn1;/*返回num,表示当前行中只有一个字符,且没有回车符*/}intdel(Hnode*Hhead,intm,intn)/*del():删除第m行,第n列位置的字符*/{Hnode*q,*q1;node*p1,*p2,*tail;inti,num=0,j,flag=0;q=Hhead;if(n==0&&m==1)return;/*第1行,第0列不存在*/if(n==0&&m1)/*若为第0列字符,但行必须大于1,执行向上行移处理*/{n=76;m=m-1;gotoxy(n,m);/*移至第m-1行,第76列*/flag=1;/*移位的标志置1*/}for(i=1;im;i++)/*定位至行单链表中的第m个元素*/q=q-nextl;p1=q-next;for(i=1;in-1;i++)/*定位至列单链表中的第n-1个元素*/p1=p1-next;p2=p1-next;/*p2指向列单链表中的第n个元素*/if(n==1)/*若是删除第m行第1列的字符*/{q-next=p1-next;free(p1);}else{p1-next=p2-next;/*在单链表中删除第m行第n列的元素*/free(p2);}/*删除掉第m行第n列的元素后,处理行单链表中第m个节点后的数据向前移的任务*/while((num=judge(Hhead,m++))0)/*执行一次judge(Head,m)后,m才加1.这里必须满足行常规字符数不为0的条件*/{p1=q-next;q1=q;if(p1!=NULL)/*若当前行非空*/{while(p1-next!=NULL)p1=p1-next;tail=p1;/*tail保存列单链表最后一个元素的地址*/q=q-nextl;/*指向下一行的元素的地址*/p1=p2=q-next;tail-next=p1;/*tail的指针域指向下一行的第一个元素的地址*/}else/*若当前行的字符个数为0,即删除该字符后,只剩下回车符,则将下一个行单链表中节点的数据域移至前一下节点的数据域*/{q=q-nextl;p1=p2=q-next;q1-next=p1;/*q1-next指向下一行的第一个元素的地址*/}for(i=0;i76-num;i++)/*当前行还有76-num个空位没有字符,在下一行的单链表中读取字符,直至遇到回车符为止*/{p1=p2;/*p1指向p2的前一个节点,p2指向行单链表中下一个节点*/p2=p2-next;if(p2-ch==13)break;/*若为回车,跳出循环*/}q-next=p2;/*在列单链表中去掉移至上行的元素*/p1-next=NULL;/*下行移至上行的最后一个元素,指针置空*/}returnflag;/*返回0:表示没有