文本编辑器C代码.docx
- 文档编号:17878613
- 上传时间:2023-08-04
- 格式:DOCX
- 页数:41
- 大小:25.54KB
文本编辑器C代码.docx
《文本编辑器C代码.docx》由会员分享,可在线阅读,更多相关《文本编辑器C代码.docx(41页珍藏版)》请在冰点文库上搜索。
文本编辑器C代码
/*文本编辑器editor源代码*/
#include
#include
#include
#include
#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('*');/*若为回车键,打印出*号*/
else
putch(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;i<24;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->ch<127&&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;i q=q->nextl; p=q->next;/*获取第m个节点的数据域*/ for(i=1;i p=p->next; if(p->ch==13)return-1;/*若第m行,第n列的字符为回车键,则返回-1*/ if(p->ch>=32&&p->ch<127)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;i 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->ch<127)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&&m>1)/*若为第0列字符,但行必须大于1,执行向上行移处理*/ { n=76; m=m-1; gotoxy(n,m);/*移至第m-1行,第76列*/ flag=1;/*移位的标志置1*/ } for(i=1;i { q=q->nextl; } p1=q->next; for(i=1;i { 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;i<76-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: 表示没有换位,返回1: 表示有换位*/ } /*执行insert()后,检验第n行及后面的数据,使其满足规则*/ inttest(Hnode*Hhead,intn) { inti=0,num1=1; node*p1,*p2,*tail,*temp1,*temp2; Hnode*q; q=Hhead; for(i=1;i q=q->nextl; tail=p1=q->next; if(p1==NULL)return;/*若此行没有任何字符,则返回*/ while(tail->next! =NULL)/*定位至列单链表中的最后一个元素*/ tail=tail->next; /*若此单链表中没有回车符且有超过76个节点时,则p1会指向此列单链表中的第76个节点*/ for(i=0;i<75;i++) { if(p1->ch==13||p1->next==NULL)break; p1=p1->next; } p2=p1->next; p1->next=NULL;/*在此行的最后一个字符的前一个字符处断行,因为插入在此行插入了一个新的字符*/ if(tail->ch! =13)/*若此行行尾不是回车键*/ { if(p1->ch==13&&q->nextl==NULL)/*若p1的数据域为回车符且行单链表中只有n个节点*/ { q->nextl=(Hnode*)malloc(sizeof(Hnode));/*新建一个行单链表节点,相当于添加一个新行*/ q->nextl->nextl=NULL; tail->next=(node*)malloc(sizeof(node));/*在tail所指节点位置开始继续准备添加字符*/ tail->next->ch=13;tail->next->next=NULL; q->nextl->next=p2;/*新行单链表节点保存此行多出的字符*/ } else/*若此行行尾和行中都没有回车键,或者q->nextl不为空*/ { q=q->nextl;/*q->nextl有可能为空*/ tail->next=q->next;/*将多出的字符与下一行的字符相连*/ q->next=p2;/**/ if(q! =NULL)test(Hhead,++n);/*若行单链表第n个节点后还有节点,继续test()的相同处理*/ } } else/*若此列单链表最后一个元素为回车符*/ { temp2=p2;/*p2指向第77个字符,或者为空(为空表示此行插入一个字符后,没有超出范围*/ while(q! =NULL&&p2! =NULL)/*q指向行列表中的第n个节点.条件: 行单链表中第n个节点存中且有第77个字符*/ {/*条件: 在行单链表中只有n个节点,且字符超过了一行规定的76个,且num1标志为1*/ if((q->nextl==NULL)&&(p1! =tail||p2! =NULL)&&(num1==1)) { num1++; q->nextl=(Hnode*)malloc(sizeof(Hnode));/*新建一个行单链表节点,准备存储此行中多出的字符*/ q->nextl->nextl=NULL;q->nextl->next=NULL;/*初始化值*/ } /*行单链表中第n+1个节点已经存在,下面为在行单链表中插入一个新的节点*/ q=q->nextl;/*q指向行列表中的第n+1个节点*/ temp1=q->next; q->next=temp2;/*q的数据域为此行中多出的字符所在的列单链表中的节点地址*/ temp2=temp1; } } } voidinsert(Hnode*Hhead,intm,intn,chara)/*第m行,第n列的位置之前一个位置,插入单字符*/ { inti; Hnode*q; node*p,*p1,*p2; q=Hhead; for(i=1;i q=q->nextl; p1=q->next; for(i=1;i p1=p1->next; p=(node*)malloc(sizeof(node));/*创建一个新的列单链表节点*/ p->ch=a;/*给此节点的数据域赋值*/ if(n==1)/*插入之前,若只有一个字符在行中,则插在此节点之前*/ { p->next=q->next; q->next=p; } else { p->next=p1->next;/*在第m行,第n列的字符前,插入一字符*/ p1->next=p; } test(Hhead,m);/*在插入新元素后,检验并处理单链表中第m行开始的元素,使其满足规则*/ } /*对控制键进行响应,A: 按键的整数值,Hhead: 行单链表的首地址*/ voidcontrol(intA,Hnode*Hhead) { voidcolorview(Hnode*,int,int);/*函数声明*/ intx,y,flag=0; x=wherex();y=wherey();/*得到当前光标的坐标值*/ if((A==CL)&&(x! =1))/*ctrl+←,当前光标不是在行首,光标移动*/ gotoxy(wherex()-1,wherey()); if((A==CL)&&(x==1))/*ctrl+←,在行首*/ gotoxy(abs(judge(Hhead,wherey()-1)),wherey()-1);/*judge(Hhead,wherey()-1)上一行的字符个数作为x值,光标移动*/ if((A==CR)&&check(Hhead,wherey(),wherex())>0)/*ctrl+→,当前光标的右边有字符,光标移动*/ { flag=1; gotoxy(wherex()+1,wherey()); } if((A==CR)&&check(Hhead,wherey()+1,1)>0&&check(Hhead,y,x)==0)/*ctrl+→,当前光标处没有字符但下一行的第一列有字符,光标移动*/ { flag=1;gotoxy(1,wherey()+1); } if((A==CR)&&x==76)/*ctrl+→,当前光标在当前行的行尾,光标移动*/ { flag=1;gotoxy(1,wherey()+1); } if(A==CR&&flag==1)/*ctrl+→,光标已经跳至新处,将当前光标所在位置的字符的坐标和值保存在r数组中*/ { r[abs(value)].col=wherex(); r[abs(value)].line=wherey(); r[abs(value)].ch=check(Hhead,r[abs(value)].line,r[abs(value)].col); if(r[abs(value)].ch==-1)r[abs(value)].ch=13;/*若第line行,第col列的字符为回车键,则返回-1*/ value--; } if(A==CL&&(x! =1||y! =1))/*ctrl+←,当前光标并不在窗口左上角,将当前光标所在位置的字符的坐标和值保存在r数组中*/ { r[abs(value)].col=wherex(); r[abs(value)].line=wherey(); r[abs(value)].ch=check(Hhead,r[abs(value)].line,r[abs(value)].col); value++; } colorview(Hhead,wherex(),wherey()); } /*用不同的前背景色显示选择的字符*/ voidcolorview(Hnode*Hhead,intx,inty) { inti; view(Hhead);/*重新显示所有文本字符*/ for(i=0;i { gotoxy(r[i].col,r[i].line); textbackground(7); textcolor(0); if(r[i].ch! =13&&r[i].ch! =-1) cprintf("%c",r[i].ch); if(r[i].ch==13||r[i].ch==-1) cprintf(""); } gotoxy(x,y); } voiddrawmenu(intm,intn)/*画菜单,m: 第几项菜单,n: 第m项的第n个子菜单*/ { inti; if(m%3==0)/*画File菜单项*/ { window(8,2,19,9); textcolor(0); textbackground(7); for(i=0;i<7;i+
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 文本 编辑器 代码