C語言實(shí)現(xiàn)文本編輯器系統(tǒng)
更新時間:2021年05月09日 07:09:42 投稿:lijiao
這篇文章主要為大家詳細(xì)介紹了C語言實(shí)現(xiàn)文本編輯器系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
本文實(shí)例為大家分享了C語言實(shí)現(xiàn)文本編輯器系統(tǒng)的具體代碼,供大家參考,具體內(nèi)容如下
/*文本編輯器editor源代碼*/
#include <stdio.h>
#include <conio.h>
#include <bios.h>
#include <math.h>
#define LEFT 0x4b00 /*←:光標(biāo)左移*/
#define RIGHT 0x4d00 /*→:光標(biāo)右移*/
#define DOWN 0x5000 /*↓鍵:光標(biāo)下移*/
#define UP 0x4800 /*↑鍵:光標(biāo)上移*/
#define ESC 0x011b /*ESC鍵:取消菜單打開操作*/
#define ENTER 0x1c0d /*回車鍵:換行*/
#define DEL 21248 /*DEL鍵:刪除當(dāng)前字符*/
#define BACK 3592 /*BackSpace鍵:刪除當(dāng)前光標(biāo)位置前一個字符*/
#define CL 29440 /*ctrl+←鍵:從右至左,選定文本*/
#define CR 29696 /*ctrl+→鍵:從左到右,選定文本*/
#define Cc 11779 /*ctrl+c鍵:將選定文本,復(fù)制一份到剪貼板中*/
#define Cv 12054 /*ctrl+v鍵:將剪貼板中的內(nèi)容復(fù)制到當(dāng)前位置*/
#define Cx 11544 /*ctrl+x鍵:對選定文本,執(zhí)行剪切操作*/
#define F1 15104 /*F1鍵:打開文件菜單*/
#define F2 15360 /*F2鍵:打開編輯菜單*/
#define F3 15616 /*F3鍵:打開幫助菜單*/
#define F10 17408 /*F10鍵:進(jìn)入文本快速預(yù)覽模式*/
int value,backup,NUM;
/*value保存有值數(shù)組元素的最大下標(biāo)值,backup保存value的副本,NUM保存當(dāng)前行中的用戶輸入的字符個數(shù)*/
typedef struct record
{
char ch; /*保存一字符*/
int col, line; /*x軸和y軸坐標(biāo)*/
}record;
record r[500]; /*定義一個有500個元素的結(jié)構(gòu)體數(shù)組,保存選定的文本字符的屬性*/
typedef struct node /*定義保存行中的單個字符的結(jié)構(gòu)*/
{
char ch; /*數(shù)據(jù)域:保存一字符*/
struct node *next; /*指針域:指向下一個結(jié)點(diǎn)的指針*/
}node;/*由此類型節(jié)點(diǎn)構(gòu)成的單鏈表,命名為:列單鏈表*/
typedef struct Hnode /*定義保存所有列單鏈表首節(jié)點(diǎn)的指針的結(jié)構(gòu)*/
{
node *next; /*指向列單鏈表的首節(jié)點(diǎn)的地址*/
struct Hnode *nextl; /*指向下一個節(jié)點(diǎn)的指針*/
}Hnode;/*由此類型節(jié)點(diǎn)構(gòu)成的單鏈表,命名為:行單鏈表*/
void drawmain() /*畫主窗口函數(shù)*/
{
int i,j;
gotoxy(1,1); /*在文本窗口中設(shè)置光標(biāo)至(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 %c File %c %c",179,17,16,179); /* | < > |*/
gotoxy(27,1); cprintf("%c %c Edit %c %c",179,17,16,179); /* | < > |*/
gotoxy(47,1); cprintf("%c %c Help %c %c",179,17,16,179); /* | < > |*/
gotoxy(5,25); /*跳至窗口底端*/
textcolor(1);
cprintf(" Row:1 Col:1");
gotoxy(68,25);
cprintf("Version 2.0");
}
void qview(Hnode *q) /*快速預(yù)覽文本:開頭:#,回車:* */
{
void view(Hnode *q); /*view()函數(shù)聲明*/
node *p;
int i;
window(1,1,80,25); /*定義文本窗口大小*/
clrscr(); /*清屏*/
/*循環(huán)讀取兩個單鏈表中的值:q是一個指向行單鏈表首節(jié)點(diǎn)的指針,
此單鏈表數(shù)據(jù)域的值為實(shí)際保存各行字符的列單鏈表p中的首節(jié)點(diǎn)地址*/
do{
p=q->next; /*p指向保存行數(shù)據(jù)的列單鏈表的首節(jié)點(diǎn)的地址*/
cprintf("#"); /*每行開頭,打印此字符,不管前面是否有回車符*/
while(p!=NULL) /*循環(huán)讀取單鏈表p中的值*/
{
if(p->ch==13) putch('*'); /*若為回車鍵,打印出*號*/
else
putch(p->ch); /*輸出各行中的字符到預(yù)覽窗口*/
p=p->next; /*指向下一個節(jié)點(diǎn)*/
}
q=q->nextl; /*指向下一個節(jié)點(diǎn)*/
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);
}
void view(Hnode *q) /*按行顯示保存在單鏈表中的文本字符,q為指向行單鏈表中第一個節(jié)點(diǎn)的指針*/
{
node *p; /*p為保存列單鏈表節(jié)點(diǎn)元素地址的指針*/
clrscr(); /*清屏*/
/*雙重循環(huán),讀取并顯示保存在單鏈表中字符*/
do{
p=q->next;
while(p!=NULL&&p->ch>=32&&p->ch<127&&p->ch!=13&&p->ch!=-1) /*指針p不能為空,且數(shù)據(jù)域必須為常規(guī)字符*/
{
putch(p->ch);/*在文本窗口中輸出該字符*/
p=p->next; /*指向下一個節(jié)點(diǎn)*/
}
q=q->nextl; /*指向下一個節(jié)點(diǎn)*/
if((p->ch==13||p->ch==-1)&&q!=NULL) gotoxy(1,wherey()+1); /*若ch為回車或EOF標(biāo)記,光標(biāo)跳至下行的開始處*/
}while(q!=NULL); /*逐行逐列顯示文本字符*/
}
int check(Hnode *Hhead,int m,int n) /*check():在單鏈表中檢查第m行第n列位置的字符,若為常規(guī)字符,則返回該字符*/
{
int i;
Hnode *q;
node *p;
q=Hhead;
for(i=1;i<m;i++) /*定位至行單鏈表中的第m個元素*/
q=q->nextl;
p=q->next;/*獲取第m個節(jié)點(diǎn)的數(shù)據(jù)域*/
for(i=1;i<n;i++) /*定位至列單鏈表中的第n個元素*/
p=p->next;
if(p->ch==13) return -1; /*若第m行,第n列的字符為回車鍵,則返回-1*/
if(p->ch>=32&&p->ch<127) return p->ch; /*若第m行,第n列的字符為常規(guī)字符,則返回該字符*/
else return 0; /*若第m行,第n列的字符既非回車符又非常規(guī)字符,則返回0*/
}
int judge(Hnode *Hhead,int m) /*judge():返回第m行中的常規(guī)字符總的個數(shù),不包括回車符*/
{
Hnode *q;
node *p;
int i,num=0;
q=Hhead;
for(i=1;i<m;i++) /*定位至行單鏈表中的第m個元素*/
q=q->nextl;
if(q==NULL) return -1; /*返回-1,表示第m行不存在*/
p=q->next;
while(p->next!=NULL)
{
p=p->next;
num++; /*統(tǒng)計(jì)第m行的字符個數(shù)*/
}
/*行尾字符還沒有判斷,接下來判斷行尾字符*/
if(p->ch==13&&num==0) return 0; /*返回0,表示當(dāng)前行只有一個回車字符*/
if(p->ch>=32&&p->ch<127) return num+1; /*返回num+1,表示當(dāng)前行的最后一個字符為常規(guī)字符*/
if(p->ch==13&&num!=0) return num; /*返回num,表示當(dāng)前行的最后一個字符為回車符,不計(jì)算在內(nèi)*/
else return 1;/*返回num,表示當(dāng)前行中只有一個字符,且沒有回車符*/
}
int del(Hnode *Hhead,int m,int n) /*del():刪除第m行,第n列位置的字符*/
{
Hnode *q,*q1;
node *p1,*p2,*tail;
int i,num=0,j,flag=0;
q=Hhead;
if(n==0&&m==1) return; /*第1行,第0列不存在*/
if(n==0&&m>1) /*若為第0列字符,但行必須大于1,執(zhí)行向上行移處理*/
{
n=76;
m=m-1;
gotoxy(n,m);/*移至第m-1行,第76列*/
flag=1; /*移位的標(biāo)志置1*/
}
for(i=1;i<m;i++) /*定位至行單鏈表中的第m個元素*/
q=q->nextl;
p1=q->next;
for(i=1;i<n-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個節(jié)點(diǎn)后的數(shù)據(jù)向前移的任務(wù)*/
while((num=judge(Hhead,m++))>0) /*執(zhí)行一次judge(Head,m)后,m才加1.這里必須滿足行常規(guī)字符數(shù)不為0的條件*/
{
p1=q->next; q1=q;
if(p1!=NULL) /*若當(dāng)前行非空*/
{
while(p1->next!=NULL)
p1=p1->next;
tail=p1;/*tail保存列單鏈表最后一個元素的地址*/
q=q->nextl; /*指向下一行的元素的地址*/
p1=p2=q->next;
tail->next=p1; /*tail的指針域指向下一行的第一個元素的地址*/
}
else /*若當(dāng)前行的字符個數(shù)為0,即刪除該字符后,只剩下回車符,則將下一個行單鏈表中節(jié)點(diǎn)的數(shù)據(jù)域移至前一下節(jié)點(diǎn)的數(shù)據(jù)域*/
{
q=q->nextl; p1=p2=q->next;
q1->next=p1;/*q1->next指向下一行的第一個元素的地址*/
}
for(i=0;i<76-num;i++)
/*當(dāng)前行還有76-num個空位沒有字符,在下一行的單鏈表中讀取字符,直至遇到回車符為止*/
{
p1=p2; /*p1指向p2的前一個節(jié)點(diǎn),p2指向行單鏈表中下一個節(jié)點(diǎn)*/
p2=p2->next;
if(p2->ch==13) break; /*若為回車,跳出循環(huán)*/
}
q->next=p2; /*在列單鏈表中去掉移至上行的元素*/
p1->next=NULL;/*下行移至上行的最后一個元素,指針置空*/
}
return flag; /*返回0:表示沒有換位,返回1:表示有換位*/
}
/*執(zhí)行insert()后,檢驗(yàn)第n行及后面的數(shù)據(jù),使其滿足規(guī)則*/
int test(Hnode *Hhead,int n)
{
int i=0,num1=1;
node *p1,*p2,*tail,*temp1,*temp2;
Hnode *q;
q=Hhead;
for(i=1;i<n;i++) /*定位至行單鏈表中的第n個元素*/
q=q->nextl;
tail=p1=q->next;
if(p1==NULL) return; /*若此行沒有任何字符,則返回*/
while(tail->next!=NULL) /*定位至列單鏈表中的最后一個元素*/
tail=tail->next;
/*若此單鏈表中沒有回車符且有超過76個節(jié)點(diǎn)時,則p1會指向此列單鏈表中的第76個節(jié)點(diǎn)*/
for(i=0;i<75;i++)
{
if(p1->ch==13||p1->next==NULL) break;
p1=p1->next;
}
p2=p1->next;
p1->next=NULL; /*在此行的最后一個字符的前一個字符處斷行,因?yàn)椴迦朐诖诵胁迦肓艘粋€新的字符*/
if(tail->ch!=13) /*若此行行尾不是回車鍵*/
{
if(p1->ch==13&&q->nextl==NULL)/*若p1的數(shù)據(jù)域?yàn)榛剀嚪倚袉捂湵碇兄挥衝個節(jié)點(diǎn)*/
{
q->nextl=(Hnode *)malloc(sizeof(Hnode)); /*新建一個行單鏈表節(jié)點(diǎn),相當(dāng)于添加一個新行*/
q->nextl->nextl=NULL;
tail->next=(node *)malloc(sizeof(node));/*在tail所指節(jié)點(diǎn)位置開始繼續(xù)準(zhǔn)備添加字符*/
tail->next->ch=13; tail->next->next=NULL;
q->nextl->next=p2; /*新行單鏈表節(jié)點(diǎn)保存此行多出的字符*/
}
else /*若此行行尾和行中都沒有回車鍵,或者q->nextl不為空*/
{
q=q->nextl;/*q->nextl有可能為空*/
tail->next=q->next;/*將多出的字符與下一行的字符相連*/
q->next=p2;/**/
if(q!=NULL) test(Hhead,++n); /*若行單鏈表第n個節(jié)點(diǎn)后還有節(jié)點(diǎn),繼續(xù)test()的相同處理*/
}
}
else /*若此列單鏈表最后一個元素為回車符*/
{
temp2=p2; /*p2指向第77個字符,或者為空(為空表示此行插入一個字符后,沒有超出范圍*/
while(q!=NULL&&p2!=NULL) /*q指向行列表中的第n個節(jié)點(diǎn).條件:行單鏈表中第n個節(jié)點(diǎn)存中且有第77個字符*/
{ /*條件:在行單鏈表中只有n個節(jié)點(diǎn),且字符超過了一行規(guī)定的76個,且num1標(biāo)志為1*/
if((q->nextl==NULL)&&(p1!=tail||p2!=NULL)&&(num1==1))
{
num1++;
q->nextl=(Hnode *)malloc(sizeof(Hnode)); /*新建一個行單鏈表節(jié)點(diǎn),準(zhǔn)備存儲此行中多出的字符*/
q->nextl->nextl=NULL; q->nextl->next=NULL; /*初始化值*/
}
/*行單鏈表中第n+1個節(jié)點(diǎn)已經(jīng)存在,下面為在行單鏈表中插入一個新的節(jié)點(diǎn)*/
q=q->nextl; /*q指向行列表中的第n+1個節(jié)點(diǎn)*/
temp1=q->next;
q->next=temp2; /*q的數(shù)據(jù)域?yàn)榇诵兄卸喑龅淖址诘牧袉捂湵碇械墓?jié)點(diǎn)地址*/
temp2=temp1;
}
}
}
void insert(Hnode *Hhead,int m,int n, char a) /*第m行,第n列的位置之前一個位置,插入單字符*/
{
int i;
Hnode *q;
node *p,*p1,*p2;
q=Hhead;
for(i=1;i<m;i++) /*定位至行單鏈表中的第m個元素*/
q=q->nextl;
p1=q->next;
for(i=1;i<n-1;i++) /*定位至列單鏈表中的第n-1個元素*/
p1=p1->next;
p=(node *)malloc(sizeof(node)); /*創(chuàng)建一個新的列單鏈表節(jié)點(diǎn)*/
p->ch=a; /*給此節(jié)點(diǎn)的數(shù)據(jù)域賦值*/
if(n==1) /*插入之前,若只有一個字符在行中,則插在此節(jié)點(diǎn)之前*/
{
p->next=q->next;
q->next=p;
}
else
{
p->next=p1->next; /*在第m行,第n列的字符前,插入一字符*/
p1->next=p;
}
test(Hhead,m); /*在插入新元素后,檢驗(yàn)并處理單鏈表中第m行開始的元素,使其滿足規(guī)則*/
}
/*對控制鍵進(jìn)行響應(yīng),A:按鍵的整數(shù)值,Hhead:行單鏈表的首地址*/
void control(int A, Hnode *Hhead)
{
void colorview(Hnode *,int,int); /*函數(shù)聲明*/
int x,y,flag=0;
x=wherex(); y=wherey(); /*得到當(dāng)前光標(biāo)的坐標(biāo)值*/
if((A==CL)&&(x!=1)) /*ctrl+←,當(dāng)前光標(biāo)不是在行首,光標(biāo)移動*/
gotoxy(wherex()-1,wherey());
if((A==CL)&&(x==1)) /*ctrl+←,在行首*/
gotoxy(abs(judge(Hhead,wherey()-1)),wherey()-1); /*judge(Hhead,wherey()-1)上一行的字符個數(shù)作為x值,光標(biāo)移動*/
if((A==CR)&&check(Hhead,wherey(),wherex())>0) /*ctrl+→,當(dāng)前光標(biāo)的右邊有字符,光標(biāo)移動*/
{ flag=1; gotoxy(wherex()+1,wherey()); }
if((A==CR)&&check(Hhead,wherey()+1,1)>0&&check(Hhead,y,x)==0) /*ctrl+→,當(dāng)前光標(biāo)處沒有字符但下一行的第一列有字符,光標(biāo)移動*/
{ flag=1; gotoxy(1,wherey()+1); }
if((A==CR)&&x==76) /*ctrl+→,當(dāng)前光標(biāo)在當(dāng)前行的行尾,光標(biāo)移動*/
{ flag=1; gotoxy(1,wherey()+1); }
if(A==CR&&flag==1) /*ctrl+→,光標(biāo)已經(jīng)跳至新處,將當(dāng)前光標(biāo)所在位置的字符的坐標(biāo)和值保存在r數(shù)組中*/
{
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+←,當(dāng)前光標(biāo)并不在窗口左上角,將當(dāng)前光標(biāo)所在位置的字符的坐標(biāo)和值保存在r數(shù)組中*/
{
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());
}
/*用不同的前背景色顯示選擇的字符*/
void colorview(Hnode *Hhead,int x,int y)
{
int i;
view(Hhead);/*重新顯示所有文本字符*/
for(i=0;i<abs(value);i++) /*value為數(shù)組下標(biāo)*/
{
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);
}
void drawmenu(int m,int n) /*畫菜單,m:第幾項(xiàng)菜單,n:第m項(xiàng)的第n個子菜單*/
{
int i;
if(m%3==0) /*畫File菜單項(xiàng)*/
{
window(8,2,19,9);
textcolor(0);
textbackground(7);
for(i=0;i<7;i++) /*在上面定義的文本窗口中先輸出7個空行*/
{
gotoxy(1,1+i);
insline();
}
window(1,1,80,25);
gotoxy(7,1);
for(i=1;i<=7;i++)
{
gotoxy(8,1+i);
cprintf("%c",179); /*窗口內(nèi)文本的輸出函數(shù),在窗口左邊輸出 | */
gotoxy(19,1+i);
cprintf("%c",179); /*窗口內(nèi)文本的輸出函數(shù),在窗口右邊輸出 | */
}
for(i=1;i<=11;i++)
{
gotoxy(8+i,2);
cprintf("%c",196); /*窗口內(nèi)文本的輸出函數(shù),在窗口上邊輸出 - */
gotoxy(8+i,9);
cprintf("%c",196); /*窗口內(nèi)文本的輸出函數(shù),在窗口下邊輸出 - */
}
textbackground(0);
gotoxy(10,10); cprintf(" "); /*輸出下邊的陰影效果*/
for(i=0;i<9;i++)
{
gotoxy(20,2+i);
cprintf(" "); /*輸出右邊的陰影效果*/
}
/*以上為顯示菜單項(xiàng)的外觀*/
textbackground(7);
gotoxy(8,2); cprintf("%c",218); /*輸出四個邊角表格符*/
gotoxy(8,9); cprintf("%c",192);
gotoxy(19,2); cprintf("%c",191);
gotoxy(19,9); cprintf("%c",217);
gotoxy(9,3); cprintf(" New ");
gotoxy(9,4); cprintf(" Open ");
gotoxy(9,5); cprintf(" Save ");
gotoxy(9,6); cprintf(" Save as");
for(i=1;i<=10;i++)
{
gotoxy(8+i,7);
cprintf("%c",196); /*在Save as下輸出一行分隔符*/
}
gotoxy(9,8); cprintf(" Exit");
textcolor(15); textbackground(0);
gotoxy(7,1);
cprintf("%c %c File %c %c",179,17,16,179);
switch(n%5)
{
case 0:gotoxy(9,3); cprintf(" New "); break;
case 1:gotoxy(9,4); cprintf(" Open "); break;
case 2:gotoxy(9,5); cprintf(" Save "); break;
case 3:gotoxy(9,6); cprintf(" Save as "); break;
case 4:gotoxy(9,8); cprintf(" Exit "); break;
}
}
/********************************************************/
if(m%3==1) /*畫Edit菜單項(xiàng)*/
{
window(28,2,38,7);
textcolor(0);
textbackground(7);
for(i=0;i<5;i++)
{
gotoxy(1,1+i);
insline();
}
window(1,1,80,25);
gotoxy(27,1);
for(i=1;i<=5;i++)
{
gotoxy(28,1+i);
cprintf("%c",179);
gotoxy(39,1+i);
cprintf("%c",179);
}
for(i=1;i<=11;i++)
{
gotoxy(28+i,2);
cprintf("%c",196);
gotoxy(28+i,7);
cprintf("%c",196);
}
textbackground(0);
gotoxy(30,8); cprintf(" ");
for(i=0;i<7;i++)
{
gotoxy(40,2+i);
cprintf(" ");
}
textbackground(7);
gotoxy(28,2); cprintf("%c",218);
gotoxy(28,7); cprintf("%c",192);
gotoxy(39,2); cprintf("%c",191);
gotoxy(39,7); cprintf("%c",217);
gotoxy(29,3); cprintf(" Cut ");
gotoxy(29,4); cprintf(" Copy ");
gotoxy(29,5); cprintf(" Paste ");
gotoxy(29,6); cprintf(" Clear ");
textcolor(15); textbackground(0);
gotoxy(27,1);
cprintf("%c %c Edit %c %c",179,17,16,179);
switch(n%4)
{
case 0:gotoxy(29,3); cprintf(" Cut "); break;
case 1:gotoxy(29,4); cprintf(" Copy "); break;
case 2:gotoxy(29,5); cprintf(" Paste "); break;
case 3:gotoxy(29,6); cprintf(" Clear "); break;
}
}
/*********************************************************/
if(m%3==2) /*畫Help菜單項(xiàng)3*/
{
window(48,2,48,6);
textcolor(0);
textbackground(7);
for(i=0;i<3;i++)
{
gotoxy(1,1+i);
insline();
}
window(1,1,80,25);
gotoxy(47,1);
for(i=1;i<=5;i++)
{
gotoxy(48,1+i);
cprintf("%c",179);
gotoxy(59,1+i);
cprintf("%c",179);
}
for(i=1;i<=11;i++)
{
gotoxy(48+i,2);
cprintf("%c",196);
gotoxy(48+i,6);
cprintf("%c",196);
}
textbackground(0);
gotoxy(50,7); cprintf(" ");
for(i=0;i<6;i++)
{
gotoxy(60,2+i);
cprintf(" ");
}
textbackground(7);
gotoxy(48,2); cprintf("%c",218);
gotoxy(48,6); cprintf("%c",192);
gotoxy(59,2); cprintf("%c",191);
gotoxy(59,6); cprintf("%c",217);
gotoxy(49,3); cprintf("Help... ");
gotoxy(49,5); cprintf("About... ");
for(i=1;i<=10;i++)
{
gotoxy(48+i,4);
cprintf("%c",196);
}
textcolor(15); textbackground(0);
gotoxy(47,1);
cprintf("%c %c Help %c %c",179,17,16,179);
switch(n%2)
{
case 0:gotoxy(49,3); cprintf("Help... "); break;
case 1:gotoxy(49,5); cprintf("About... "); break;
}
}
}
int menuctrl(Hnode *Hhead,int A) /*菜單控制*/
{
int x,y,i,B,value,flag=100,a,b;
x=wherex(); y=wherey();
if(A==F1) { drawmenu(0,flag); value=300; } /*顯示File及其子菜單,并將光帶顯示在第一個子菜單上*/
if(A==F2) { drawmenu(1,flag); value=301; } /*顯示Edit及其子菜單,并將光帶顯示在第一個子菜單上*/
if(A==F3) { drawmenu(2,flag); value=302; } /*顯示Help及其子菜單,并將光帶顯示在第一個子菜單上*/
if(A==F1||A==F2||A==F3)
{
while((B=bioskey(0))!=ESC) /*選擇用戶按鍵*/
{
if(flag==0) flag=100;
if(value==0) value=300; /*此value為局部變量*/
if(B==UP) drawmenu(value,--flag); /*循環(huán)上下移*/
if(B==DOWN) drawmenu(value,++flag); /*循環(huán)上下移*/
if(B==LEFT) /*菜單項(xiàng)之間循環(huán)選擇(左移)*/
{
flag=100;
drawmain();
window(2,2,79,23);
textbackground(9);
for(i=0;i<24;i++)
insline();
window(3,3,78,23);
textcolor(10);
view(Hhead);
drawmenu(--value,flag);
}
if(B==RIGHT)/*菜單項(xiàng)之間循環(huán)選擇(右移)*/
{
flag=100;
drawmain();
window(2,2,79,23);
textbackground(9);
for(i=0;i<24;i++)
insline();
window(3,3,78,23);
textcolor(10);
view(Hhead);
drawmenu(++value,flag);
}
if(B==ENTER) /*選中某主菜單項(xiàng)的子菜單項(xiàng)(選中某項(xiàng))*/
{
if(value%3==0) b=5; /*File下有5個子菜單項(xiàng)*/
if(value%3==1) b=4; /*Edit下有4個子菜單項(xiàng)*/
if(value%3==2) b=2; /*Help下有2個子菜單項(xiàng)*/
a=(value%3)*10+flag%b;/*a表示選擇子菜單的編號*/
drawmain();
window(2,2,79,23);
textbackground(9);
for(i=0;i<24;i++)
insline();
window(3,3,78,23);
textcolor(10);
view(Hhead);
gotoxy(x,y);
if(a==0) return 100; /*New*/
if(a==1) return 101; /*Open*/
if(a==2) return 102; /*Save*/
if(a==3) return 103; /*Save As*/
if(a==4) exit(0); /*Exit*/
if(a==10) return Cx; /*Cut*/
if(a==11) return Cc; /*Copy*/
if(a==12) return Cv; /*Paste*/
if(a==13) return DEL;/*Clear*/
if(a==20) return 120; /*Help... */
if(a==21) return 121; /*About...*/
}
gotoxy(x+2,y+2);
}
/*若按鍵非F1、F2、F3*/
drawmain();
window(2,2,79,23);
textbackground(9);
for(i=0;i<24;i++)
insline();
window(3,3,78,23);
textcolor(10);
view(Hhead);
gotoxy(x,y);
}
return A;
}
/*將head所指的行單鏈表中所指的各個列單鏈表中的數(shù)據(jù)域的值寫入文件,文件路徑和文件名由用戶指定*/
void save(Hnode *head)
{
FILE* fp;
Hnode *q;
node *p;
int count=0,x,y;
char filename[10]; /*保存文件名*/
q=head;
clrscr();/*清屏*/
printf("Enter infile name,for example [c:\\wb.txt]:");/*輸入文件名格式*/
scanf("%s",filename); /*輸入文件名*/
fp=fopen(filename,"w");
if(fp==NULL) /*打開文件失敗*/
{
printf("\n=====>open file error!\n");
getchar();
return ;
}
do{
p=q->next; /*指向node類型的數(shù)據(jù)*/
while(p!=NULL)
{ if((int)p->ch==13)
{
fputc('\n',fp);p=p->next; count++;
}
else
{fputc(p->ch, fp);
p=p->next;
count++;}
}
q=q->nextl;
}while(q!=NULL);
fclose(fp); /*關(guān)閉此文件*/
return ;
}
/*文件另存為:將head所指的行單鏈表中所指的各個列單鏈表中的數(shù)據(jù)域的值寫入文件,文件路徑和文件名由用戶指定*/
void saveas(Hnode *head)
{
FILE* fp;
Hnode *q;
node *p;
int count=0,x,y;
char filename[10]; /*保存文件名*/
q=head;
clrscr();/*清屏*/
printf("Enter infile name,for example [c:\\wb.txt]:");/*輸入文件名格式*/
scanf("%s",filename); /*輸入文件名*/
fp=fopen(filename,"w");
if(fp==NULL) /*打開文件失敗*/
{
printf("\n=====>open file error!\n");
getchar();
return ;
}
do{
p=q->next; /*指向node類型的數(shù)據(jù)*/
while(p!=NULL)
{ if((int)p->ch==13)
{
fputc('\n',fp);p=p->next; count++;
}
else
{fputc(p->ch, fp);
p=p->next;
count++;}
}
q=q->nextl;
}while(q!=NULL);
fclose(fp); /*關(guān)閉此文件*/
return ;
}
/*從任意文本文件中讀取文件內(nèi)容,保存至行單鏈表和列單鏈表形式的數(shù)據(jù)結(jié)構(gòu)中*/
void opens(Hnode *Hp)
{
FILE* fp;
Hnode *q11,*q22;
node *p11,*p22,*hp;
char temp;
int count=0,flags=1;
char filename[10]; /*保存文件名*/
clrscr();/*清屏*/
printf("Enter infile name,for example [c:\\wb.txt]:");/*輸入文件名格式*/
scanf("%s",filename); /*輸入文件名*/
fp=fopen(filename,"r");/*以只讀方式打開文件,filename必須要存在*/
if(fp==NULL)/*打開文件失敗*/
{ textbackground(2);
textcolor(13);
cprintf("open file error!");
getchar();
exit(0) ;
}
q11=Hp;
while(!feof(fp))
{ count=0;flags=1;
q22=(Hnode *)malloc(sizeof(Hnode));/*新建一個行單鏈表中的節(jié)點(diǎn)*/
p11=(node *)malloc(sizeof(node)); /*新建一個列單鏈表中的節(jié)點(diǎn)*/
while((temp=fgetc(fp))!=10&&count<=76&&!feof(fp)) /*循環(huán)結(jié)束,表示在單鏈表中一行處理完畢,開始新行*/
{ p22=(node *)malloc(sizeof(node));/*新建一個列單鏈表中的節(jié)點(diǎn)*/
if(flags==1) {hp=p22;flags=0;} /*hp保存列單鏈表中的首節(jié)點(diǎn)的地址*/
p22->ch=temp; p22->next=NULL;
p11->next=p22; p11=p22;
count++;
}
if(temp==10){ /*若為換行符,將其轉(zhuǎn)換為回車符,因?yàn)樵诔绦蛑?,是按回車符處理?/
p22=(node *)malloc(sizeof(node));p22->ch=13; p22->next=NULL;
p11->next=p22; p11=p22;
}
if(!feof(fp))/*若沒此條件,文件最后一行會處理兩次.*/
{q22->next=hp;q22->nextl=NULL; /*將存儲了字符的新列單鏈表與行單鏈表中的新節(jié)點(diǎn)建立關(guān)聯(lián)*/
q11->nextl=q22;q11=q22;}
}
fclose(fp);
Hp=Hp->nextl;/*因?yàn)镠p的所在節(jié)點(diǎn)的數(shù)據(jù)域?yàn)榭?,所以Hp=Hp->nextl*/
return ;
}
void main()
{
char a;
int i,A,x,y,flag=0,b;
Hnode *Hhead,*q;
node *p1,*p2;
Hhead=(Hnode *)malloc(sizeof(Hnode)); /*為行單鏈表中首節(jié)點(diǎn)分配內(nèi)存空間*/
q=Hhead; Hhead->nextl=NULL;
p1=p2=q->next=(node *)malloc(sizeof(node)); /*為列單鏈表中首節(jié)點(diǎn)分配內(nèi)存空間*/
p1->ch=13; p1->next=NULL;
drawmain(); /*顯示主窗口*/
window(2,2,79,23);
textbackground(9);
for(i=0;i<24;i++)
insline();
window(3,3,78,23);
textcolor(10);
while(1)
{
while(bioskey(1)==0) continue; /*等待用戶按鍵*/
a=A=bioskey(0); /*返回輸入的字符的鍵值*/
if(a>=32&&a<127) /*若輸入為常規(guī)字符或回車鍵*/
{
if(check(Hhead,wherey(),wherex())<=0)/*當(dāng)前位置沒有字符且輸入是常規(guī)字符,則執(zhí)行添加字符操作*/
{
NUM++;
p2->ch=a;
putch(a);
if(NUM==76) /*連續(xù)輸入滿行,分別生成一個新的行單鏈表和列單鏈表節(jié)點(diǎn)*/
{
p2->next=NULL;
q->nextl=(Hnode *)malloc(sizeof(Hnode));
q=q->nextl; q->nextl=NULL; q->next=NULL;
p1=p2=q->next=(node *)malloc(sizeof(node));
p1->ch=13; p1->next=NULL;
NUM=0;
}
else /*連續(xù)輸入未滿一行,生成一個新的列單鏈表節(jié)點(diǎn)*/
{
p2->next=(node *)malloc(sizeof(node));
p2=p2->next;
p2->ch=13;
p2->next=NULL;
}
}
else /*當(dāng)前位置有字符且輸入是常規(guī)字符,則執(zhí)行插入字符操作*/
{
x=wherex(); y=wherey();
insert(Hhead,wherey(),wherex(),a);
NUM++;
view(Hhead);
gotoxy(x,y);
}
}
/*若輸入為回車鍵*/
if(a==13)
{
gotoxy(1,wherey()+1);
q->nextl=(Hnode *)malloc(sizeof(Hnode));
q=q->nextl; q->nextl=NULL; q->next=NULL;
p1=p2=q->next=(node *)malloc(sizeof(node));
p1->ch=13; p1->next=NULL;
NUM=0;
}
x=wherex(); y=wherey();
/*文本窗口中左移,當(dāng)前光標(biāo)不在窗口的第1列*/
if((A==LEFT)&&(x!=1)) gotoxy(wherex()-1,wherey());
/*文本窗口中左移,當(dāng)前光標(biāo)在窗口的第1列*/
if((A==LEFT)&&(x==1)) gotoxy(abs(judge(Hhead,wherey()-1)),wherey()-1);
/*文本窗口中右移,若當(dāng)前光標(biāo)的右邊一位有字符*/
if((A==RIGHT)&&check(Hhead,wherey(),wherex())>0) gotoxy(wherex()+1,wherey());
/*文本窗口中右移至下行的第1列,若當(dāng)前光標(biāo)位置沒有字符且下行的第1列有字符*/
if((A==RIGHT)&&check(Hhead,wherey()+1,1)!=0&&check(Hhead,y,x)<=0) gotoxy(1,wherey()+1);
/*右移*/
if((A==RIGHT)&&x==76) gotoxy(1,wherey()+1);
/*上移*/
if((A==UP)&&check(Hhead,wherey()-1,wherex())!=0) gotoxy(wherex(),wherey()-1);
/*上移*/
if((A==UP)&&check(Hhead,wherey()-1,wherex())<=0)
{
if(judge(Hhead,wherey()-1)==0)
gotoxy(-judge(Hhead,wherey()-1)+1,wherey()-1);
else
gotoxy(-judge(Hhead,wherey()-1),wherey()-1);
}
/*下移*/
if((A==DOWN)&&check(Hhead,wherey()+1,wherex())!=0)
gotoxy(wherex(),wherey()+1);
/*處理BackSpace鍵*/
if(A==BACK) /*處理BackSpace鍵*/
{
flag=del(Hhead,wherey(),wherex()-1);
x=wherex()-1; y=wherey();
view(Hhead);
if(flag==0)
{
if(x!=0) gotoxy(x,y);
else gotoxy(x+1,y);
}
if(flag==1)
{
gotoxy(x+1,y);
flag=0;
}
}
/*處理菜單按鍵F1 F2 F3*/
if((A==F1)||(A==F2)||(A==F3)||(a<32||a>127))
{ A=menuctrl(Hhead,A);
if(A==100){main();} /*新建文件*/
if(A==101){ /*打開文件*/
Hhead=(Hnode *)malloc(sizeof(Hnode));
opens(Hhead);
getchar();clrscr();gotoxy(3,3);view(Hhead);
}
/*保存文件*/
if(A==102){save(Hhead);clrscr();cprintf("save successfully!");getch();gotoxy(3,3);view(Hhead);}
/*文件另存為*/
if(A==103){saveas(Hhead);clrscr();cprintf("save as successfully!");getch();gotoxy(3,3);view(Hhead);}
/*幫助*/
if(A==120){clrscr();cprintf("<Help> F1:File F2:Edit F3:Help ");
getch();gotoxy(3,3);view(Hhead);}
if(A==121){clrscr();cprintf("Abort:Version 2.0 Tel:XXXXXXXXXX");getch();gotoxy(3,3);view(Hhead);}
}
/*處理DEL鍵,刪除當(dāng)前位置的單個字符*/
if(A==DEL)
{
x=wherex(); y=wherey();
del(Hhead,wherey(),wherex());
view(Hhead);
gotoxy(x,y);
}
/*處理已經(jīng)選定文本字符后,按DEL鍵的情況*/
if(A==DEL&&value!=0)
{
if(value>0)
x=wherex(), y=wherey();
else
x=r[0].col, y=r[0].line;
for(i=0;i<abs(value);i++)
{
if(value>0)
del(Hhead,r[i].line,r[i].col);
if(value<0)
del(Hhead,r[abs(value)-1-i].line,r[abs(value)-1-i].col);
}
value=0; /*此value為全局變量*/
view(Hhead);
gotoxy(x,y);
}
/*處理Ctrl+x按鍵*/
if(A==Cx&&value!=0)
{
if(value>0)
x=wherex(), y=wherey();
else
x=r[0].col, y=r[i].line;
for(i=0;i<abs(value);i++)
{
if(value>0)
del(Hhead,r[i].line,r[i].col);
if(value<0)
del(Hhead,r[abs(value)-1-i].line,r[abs(value)-1-i].col);
}
backup=value; /*保存r數(shù)組的有值元素的最大下標(biāo)值*/
value=0; /*此value為全局變量*/
view(Hhead);
gotoxy(x,y);
}
/*處理Ctrl+c按鍵*/
if(A==Cc&&value!=0)
{
x=wherex(); y=wherey();
backup=value; value=0; /*此value為全局變量*/
view(Hhead);
gotoxy(x,y);
}
/*處理Ctrl+v按鍵*/
if(A==Cv&&backup!=0)
{
x=wherex(); y=wherey();
if(backup<0) /*Ctrl+右移鍵選定的文本,貼切此當(dāng)前位置*/
for(i=0;i<abs(backup);i++)
insert(Hhead,y,x+i,r[i].ch);/*逐個插入*/
if(backup>0) /*Ctrl+左移鍵選定的文本,貼切此當(dāng)前位置*/
for(i=0;i<backup;i++)
insert(Hhead,y,x+i,r[backup-1-i].ch);
view(Hhead);
gotoxy(x,y);
}
/*快速預(yù)覽*/
if(A==F10)
{
qview(Hhead);
view(Hhead);
gotoxy(x,y);
}
/*處理Ctrl+左移鍵或右移鍵*/
if(A==CL||A==CR) control(A,Hhead);
/*顯示當(dāng)前行列號*/
x=wherex(); y=wherey();
window(1,1,80,25);
textcolor(0);
textbackground(7);
gotoxy(10,25); /*第25行,第10列,輸出當(dāng)前行號wherey()*/
cprintf("%-3d",y);
gotoxy(24,25); /*第25行,第24列*/
cprintf("%-3d",x);
window(3,3,78,23);
textcolor(10);
gotoxy(x,y);
textcolor(10);
textbackground(1);
}
}
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
C語言數(shù)據(jù)結(jié)構(gòu)與算法之圖的遍歷(二)
這篇文章主要是介紹了利用廣度優(yōu)先算法實(shí)現(xiàn)圖的遍歷,文中利用圖文詳細(xì)的介紹了實(shí)現(xiàn)步驟,對我們學(xué)習(xí)數(shù)據(jù)結(jié)構(gòu)與算法有一定的幫助,需要的朋友可以參考一下2021-12-12
C語言實(shí)現(xiàn)將字符串轉(zhuǎn)換為數(shù)字的方法
這篇文章主要介紹了C語言實(shí)現(xiàn)將字符串轉(zhuǎn)換為數(shù)字的方法,涉及系統(tǒng)函數(shù)atoi()函數(shù)的使用技巧,需要的朋友可以參考下2014-12-12
C語言結(jié)構(gòu)體(struct)常見使用方法(細(xì)節(jié)問題)
這篇文章主要介紹了C語言結(jié)構(gòu)體(struct)常見使用方法(細(xì)節(jié)問題),需要的朋友可以參考下2017-03-03
Ubuntu16.04下配置VScode的C/C++開發(fā)環(huán)境
這篇文章主要介紹了Ubuntu16.04下配置VScode的C/C++開發(fā)環(huán)境的教程,本文通過圖文并茂的形式給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-03-03
淺析C++標(biāo)準(zhǔn)庫元組(tuple)源碼
這篇文章主要介紹了C++標(biāo)準(zhǔn)庫元組(tuple)源碼,介紹了什么是元組以及用法,并進(jìn)行了源碼分析,需要的朋友可以參考下2015-08-08
Linux下Select多路復(fù)用實(shí)現(xiàn)簡易聊天室示例
大家好,本篇文章主要講的是Linux下Select多路復(fù)用實(shí)現(xiàn)簡易聊天室示例,感興趣的同學(xué)趕快來看一看吧,對你有幫助的話記得收藏一下,方便下次瀏覽2021-12-12

