C language implements text editor system
- 2020-06-03 07:51:39
- OfStack
This article shares the C language text editor system specific code for your reference, the specific content is as follows
/* Text editor editor The source code */
#include <stdio.h>
#include <conio.h>
#include <bios.h>
#include <math.h>
#define LEFT 0x4b00 /* please : Move the cursor to the left */
#define RIGHT 0x4d00 /* - move the cursor to the right */
#define DOWN 0x5000 /* ↓ key: Cursor down */
#define UP 0x4800 /* Arrow key: cursor up */
#define ESC 0x011b /*ESC Key: Cancel menu open operation */
#define ENTER 0x1c0d /* Enter key: line feed */
#define DEL 21248 /*DEL Key: Delete the current character */
#define BACK 3592 /*BackSpace Key: Before deleting the current cursor position 1 A character */
#define CL 29440 /*ctrl+ please Key: from right to left, select text */
#define CR 29696 /*ctrl+ - Key: from left to right, select text */
#define Cc 11779 /*ctrl+c Key: Copy the selected text 1 Copy to clipboard */
#define Cv 12054 /*ctrl+v Key: Copies the contents of the clipboard to the current location */
#define Cx 11544 /*ctrl+x Key: Perform a cut operation on the selected text */
#define F1 15104 /*F1 Key: open file menu */
#define F2 15360 /*F2 Key: Open edit menu */
#define F3 15616 /*F3 Key: Open the help menu */
#define F10 17408 /*F10 key : Enter text quick preview mode */
int value,backup,NUM;
/*value Holds the maximum subscript value of a valued array element, backup save value A copy of the NUM Saves the number of characters entered by the user in the current line */
typedef struct record
{
char ch; /* save 1 character */
int col, line; /*x Axis and y Axis coordinates */
}record;
record r[500]; /* define 1 a 500 An array of elements that hold the attributes of the selected text character */
typedef struct node /* Defines the structure of a single character in a save line */
{
char ch; /* Data domain: Save 1 character */
struct node *next; /* Pointer field: points down 1 A pointer to a node */
}node;/* The single linked list formed by this type of node is named as: column single linked list */
typedef struct Hnode /* Defines a structure that holds Pointers to the first nodes of all columns of a single linked list */
{
node *next; /* The address of the first node in a single linked list of columns */
struct Hnode *nextl; /* Point to the 1 A pointer to a node */
}Hnode;/* A single linked list of nodes of this type is named: row single linked list */
void drawmain() /* Draw the main window function */
{
int i,j;
gotoxy(1,1); /* In the text window, set the cursor to (1,1) place */
textbackground(7); /* Select the new text background color ,7 for LIGHTGRAY Light gray */
textcolor(0); /* Select the new character color in text mode 0 for BLACK black */
insline(); /* In the text window (1,1) Insert in position 1 A blank line */
for(i=1;i<=24;i++)
{
gotoxy(1,1+i); /* ( x,y) In the x The same, y++*/
cprintf("%c",196); /* Output to the left of the window -, Draw the left edge of the main window */
gotoxy(80,1+i);
cprintf("%c",196); /* To the right of the window, output - Draw the right edge of the main window */
}
for(i=1;i<=79;i++)
{
gotoxy(1+i,2); /* In the first 2 Ok, the first 2 Column started */
cprintf("%c",196); /* At the top of the window, output -*/
gotoxy(1+i,25); /* In the first 25 Ok, the first 2 Column started */
cprintf("%c",196); /* At the bottom of the window, output -*/
}
gotoxy(1,1); cprintf("%c",196); /* In the upper left corner of the window, output -*/
gotoxy(1,24); cprintf("%c",196); /* In the lower left corner of the window, output -*/
gotoxy(80,1); cprintf("%c",196); /* In the upper right corner of the window, output -*/
gotoxy(80,24); cprintf("%c",196); /* In the lower right corner of the window, output -*/
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); /* Jump to the bottom of the window */
textcolor(1);
cprintf(" Row:1 Col:1");
gotoxy(68,25);
cprintf("Version 2.0");
}
void qview(Hnode *q) /* Quick preview text: Beginning: # , enter: * */
{
void view(Hnode *q); /*view() Function declaration */
node *p;
int i;
window(1,1,80,25); /* Defines the text window size */
clrscr(); /* Clear the screen */
/* Iterate through the values in two single linked lists: q is 1 A pointer to the first node of a row single linked list,
The value of this single linked list data field is the column single linked list that actually holds the row characters p Address of the first node in */
do{
p=q->next; /*p The address of the first node in a single linked list of columns that holds row data */
cprintf("#"); /* At the beginning of each line, print this character, regardless of whether it is preceded by a carriage return */
while(p!=NULL) /* Iterate through a single linked list p The values in the */
{
if(p->ch==13) putch('*'); /* If it is enter, print it out * No. */
else
putch(p->ch); /* Prints characters from each line to the preview window */
p=p->next; /* Point to the 1 A node */
}
q=q->nextl; /* Point to the 1 A node */
printf("\n");/* The output 1 A carriage return */
}while(q!=NULL);
getch();
clrscr();
drawmain();/* Press any key and go back to the main window */
window(2,2,79,23);
textbackground(9);
for(i=0;i<24;i++)
insline(); /* insert 24 A blank line */
window(3,3,78,23);
textcolor(10);
}
void view(Hnode *q) /* Displays text characters saved in a single linked list on a line basis ,q Is the first in a single linked list pointing to a row 1 A pointer to a node */
{
node *p; /*p A pointer to the element address of a single linked list node */
clrscr(); /* Clear the screen */
/* A double loop that reads and displays characters saved in a single linked list */
do{
p=q->next;
while(p!=NULL&&p->ch>=32&&p->ch<127&&p->ch!=13&&p->ch!=-1) /* Pointer to the p Cannot be null, and the data field must be a regular character */
{
putch(p->ch);/* Prints the character in a text window */
p=p->next; /* Point to the 1 A node */
}
q=q->nextl; /* Point to the 1 A node */
if((p->ch==13||p->ch==-1)&&q!=NULL) gotoxy(1,wherey()+1); /* if ch To enter or EOF Marks, and the cursor skips to the beginning of the descent */
}while(q!=NULL); /* Display text characters line by line, column by column */
}
int check(Hnode *Hhead,int m,int n) /*check(): Check the number in a single linked list m Line first n Column position, if regular, returns that character */
{
int i;
Hnode *q;
node *p;
q=Hhead;
for(i=1;i<m;i++) /* Locate the first in a single linked list of rows m An element */
q=q->nextl;
p=q->next;/* For the first m Data fields of the nodes */
for(i=1;i<n;i++) /* Locate the first in a single linked list of columns n An element */
p=p->next;
if(p->ch==13) return -1; /* If the first m Ok, the first n Returns if the character of the column is a enter key -1*/
if(p->ch>=32&&p->ch<127) return p->ch; /* If the first m Ok, the first n The characters of the column are regular characters , Returns the character */
else return 0; /* If the first m Ok, the first n Returns if the character of the column is neither a carriage return nor an unconventional character 0*/
}
int judge(Hnode *Hhead,int m) /*judge(): Returns the first m The total number of regular characters in a line, excluding the carriage return */
{
Hnode *q;
node *p;
int i,num=0;
q=Hhead;
for(i=1;i<m;i++) /* Locate the first in a single linked list of rows m An element */
q=q->nextl;
if(q==NULL) return -1; /* return -1, According to the first m Line does not exist */
p=q->next;
while(p->next!=NULL)
{
p=p->next;
num++; /* Statistics in the first m Number of characters in a row */
}
/* The end-of-line character has not been determined yet. Next, determine the end-of-line character */
if(p->ch==13&&num==0) return 0; /* return 0, Indicates that the current row has only 1 Three carriage return characters */
if(p->ch>=32&&p->ch<127) return num+1; /* return num+1, Represents the end of the current row 1 The characters are regular characters */
if(p->ch==13&&num!=0) return num; /* return num, Represents the end of the current row 1 Six characters are carriage returns and are not counted */
else return 1;/* return num, Indicates only one in the current row 1 Six characters and no carriage return */
}
int del(Hnode *Hhead,int m,int n) /*del(): Delete the first m Ok, the first n The character of the column position */
{
Hnode *q,*q1;
node *p1,*p2,*tail;
int i,num=0,j,flag=0;
q=Hhead;
if(n==0&&m==1) return; /* The first 1 Ok, the first 0 Column does not exist */
if(n==0&&m>1) /* For the first 0 Column characters, but the row must be greater than 1, Perform row up processing */
{
n=76;
m=m-1;
gotoxy(n,m);/* Move to the first m-1 Ok, the first 76 column */
flag=1; /* The marker of a shift 1*/
}
for(i=1;i<m;i++) /* Locate the first in a single linked list of rows m An element */
q=q->nextl;
p1=q->next;
for(i=1;i<n-1;i++) /* Locate the first in a single linked list of columns n-1 An element */
p1=p1->next;
p2=p1->next; /*p2 Points to the first in a single linked list of columns n An element */
if(n==1) /* If the control is deleted m Line first 1 The characters listed */
{
q->next=p1->next;
free(p1);
}
else
{
p1->next=p2->next; /* Delete a number in a single linked list m Line first n The column element */
free(p2);
}
/* Delete the first m Line first n After the element of the column, process the row in the single linked list m The task of moving the data forward after the nodes */
while((num=judge(Hhead,m++))>0) /* perform 1 time judge(Head,m) Later, m To add 1. This must satisfy the line rule that the number of characters is not 0 The conditions of the */
{
p1=q->next; q1=q;
if(p1!=NULL) /* If the current row is not empty */
{
while(p1->next!=NULL)
p1=p1->next;
tail=p1;/*tail Save the column at the end of the single linked list 1 The address of the element */
q=q->nextl; /* Point to the 1 The address of the element of the row */
p1=p2=q->next;
tail->next=p1; /*tail The field of Pointers points down 1 The first 1 The address of the element */
}
else /* If the number of characters on the current line is 0, That is, after the character is deleted, only the carriage return is left, then the 1 Data fields of nodes in a single list of rows are moved forward 1 Data fields for the lower node */
{
q=q->nextl; p1=p2=q->next;
q1->next=p1;/*q1->next Point to the 1 The first 1 The address of the element */
}
for(i=0;i<76-num;i++)
/* The current row also has 76-num Empty space no characters, down 1 A character is read in a single linked list of rows until a carriage return is encountered */
{
p1=p2; /*p1 Point to the p2 The former 1 A node ,p2 Points to the bottom of a row singly linked list 1 A node */
p2=p2->next;
if(p2->ch==13) break; /* If it's enter, jump out of the loop */
}
q->next=p2; /* Removes elements from a single linked list of columns */
p1->next=NULL;/* Move down to the end of the row 1 Null pointer */
}
return flag; /* return 0 : indicates no transposition, return 1 : indicates transposition */
}
/* perform insert() After, check the control n Line and data to make it satisfy the rule */
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++) /* Locate the first in a single linked list of rows n An element */
q=q->nextl;
tail=p1=q->next;
if(p1==NULL) return; /* Returns if the line does not have any characters */
while(tail->next!=NULL) /* Locate to the end of a single linked list of columns 1 An element */
tail=tail->next;
/* If this single linked list has no carriage return and exceeds 76 When is, then p1 Points to the first in the single linked list of columns 76 A node */
for(i=0;i<75;i++)
{
if(p1->ch==13||p1->next==NULL) break;
p1=p1->next;
}
p2=p1->next;
p1->next=NULL; /* At the end of the trip 1 Before three characters 1 Line break at two characters , Because the insert is inserted in this row 1 New characters */
if(tail->ch!=13) /* If there is no enter at the end of this row */
{
if(p1->ch==13&&q->nextl==NULL)/* if p1 Is a carriage return character and is the only one in the row singly linked list n A node */
{
q->nextl=(Hnode *)malloc(sizeof(Hnode)); /* new 1 One row single linked list node, equivalent to add 1 A new row */
q->nextl->nextl=NULL;
tail->next=(node *)malloc(sizeof(node));/* in tail The location of the indicated node begins to prepare to add characters */
tail->next->ch=13; tail->next->next=NULL;
q->nextl->next=p2; /* The new row single linked list node holds the extra characters in that row */
}
else /* If there is no enter at the end of the line or in the line , or q->nextl Don't empty */
{
q=q->nextl;/*q->nextl It could be empty */
tail->next=q->next;/* Put the extra characters under 1 Lines are joined by characters */
q->next=p2;/**/
if(q!=NULL) test(Hhead,++n); /* If rows are singly linked to list no n There are nodes after the nodes, so let's go on test() The same treatment */
}
}
else /* If this column is at the end of a single linked list 1 The elements are carriage returns */
{
temp2=p2; /*p2 Pointing to the first 77 Two characters, or null ( Null indicates that this line is inserted 1 After 2 characters, no out of range */
while(q!=NULL&&p2!=NULL) /*q Points to the first in the column list n A node . conditions : Row the first in a single linked list n The nodes are stored and regulated 77 A character */
{ /* Condition: Only in a row single linked list n A node , And the number of characters exceeded 1 As prescribed by the line 76 A, and num1 Mark is 1*/
if((q->nextl==NULL)&&(p1!=tail||p2!=NULL)&&(num1==1))
{
num1++;
q->nextl=(Hnode *)malloc(sizeof(Hnode)); /* new 1 A single row linked list node , Prepare to store the extra characters in this row */
q->nextl->nextl=NULL; q->nextl->next=NULL; /* The initialization value */
}
/* Row the first in a single linked list n+1 The following is inserted into the row single linked list 1 A new node */
q=q->nextl; /*q Points to the first in the column list n+1 A node */
temp1=q->next;
q->next=temp2; /*q Is the address of a node in a single linked list of columns containing additional characters in the row */
temp2=temp1;
}
}
}
void insert(Hnode *Hhead,int m,int n, char a) /* The first m Ok, the first n Before the column position 1 A position to insert a single character */
{
int i;
Hnode *q;
node *p,*p1,*p2;
q=Hhead;
for(i=1;i<m;i++) /* Locate the first in a single linked list of rows m An element */
q=q->nextl;
p1=q->next;
for(i=1;i<n-1;i++) /* Locate the first in a single linked list of columns n-1 An element */
p1=p1->next;
p=(node *)malloc(sizeof(node)); /* create 1 A new column single linked list node */
p->ch=a; /* Assign a value to the data domain of this node */
if(n==1) /* Insert before if only 1 In a line, is inserted before this node */
{
p->next=q->next;
q->next=p;
}
else
{
p->next=p1->next; /* In the first m Ok, the first n Before the character of the column, insert 1 character */
p1->next=p;
}
test(Hhead,m); /* After inserting a new element, verify and process the first in the single linked list m The element at the beginning of the row so that it satisfies the rule */
}
/* Responding to the control keys, A : Integer value of the key, Hhead: The first address of a single linked list of rows */
void control(int A, Hnode *Hhead)
{
void colorview(Hnode *,int,int); /* Function declaration */
int x,y,flag=0;
x=wherex(); y=wherey(); /* Gets the coordinate value of the current cursor */
if((A==CL)&&(x!=1)) /*ctrl+ please , the current cursor is not the beginning of the line , The cursor */
gotoxy(wherex()-1,wherey());
if((A==CL)&&(x==1)) /*ctrl+ please please , */
gotoxy(abs(judge(Hhead,wherey()-1)),wherey()-1); /*judge(Hhead,wherey()-1) on 1 The number of characters on a line as x Value, cursor movement */
if((A==CR)&&check(Hhead,wherey(),wherex())>0) /*ctrl+ - , There are characters to the right of the current cursor and the cursor moves */
{ flag=1; gotoxy(wherex()+1,wherey()); }
if((A==CR)&&check(Hhead,wherey()+1,1)>0&&check(Hhead,y,x)==0) /*ctrl+ - , There are no characters at the current cursor but below 1 The first 1 The column has characters and the cursor moves */
{ flag=1; gotoxy(1,wherey()+1); }
if((A==CR)&&x==76) /*ctrl+ - , the current cursor moves at the end of the current line */
{ flag=1; gotoxy(1,wherey()+1); }
if(A==CR&&flag==1) /*ctrl+ - , the cursor has jumped to a new position, and the coordinates and values of the characters at the current cursor position are saved in r In the array */
{
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; /* If the first line Ok, the first col Returns if the character of the column is a enter key -1*/
value--;
}
if(A==CL&&(x!=1||y!=1)) /*ctrl+ please , The current cursor is not in the upper-left corner of the window , Saves the coordinates and values of the character at the current cursor position in r In the array */
{
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());
}
/* Displays selected characters with different front background colors */
void colorview(Hnode *Hhead,int x,int y)
{
int i;
view(Hhead);/* Redisplay all text characters */
for(i=0;i<abs(value);i++) /*value Is the index of the array */
{
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) /* Draw the menu ,m: Which menu item, n : the first m The first item n Sub menu */
{
int i;
if(m%3==0) /* draw File A menu item */
{
window(8,2,19,9);
textcolor(0);
textbackground(7);
for(i=0;i<7;i++) /* Output first in the text window defined above 7 A blank line */
{
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); /* Output function for text in the window, to the left of the window | */
gotoxy(19,1+i);
cprintf("%c",179); /* Output function for text in the window, to the right of the window | */
}
for(i=1;i<=11;i++)
{
gotoxy(8+i,2);
cprintf("%c",196); /* Output function for text in the window, output above the window - */
gotoxy(8+i,9);
cprintf("%c",196); /* Output function for text in the window, output below the window - */
}
textbackground(0);
gotoxy(10,10); cprintf(" "); /* Print the shadow effect below */
for(i=0;i<9;i++)
{
gotoxy(20,2+i);
cprintf(" "); /* Outputs the shadow effect on the right */
}
/* Above is what the menu item should look like */
textbackground(7);
gotoxy(8,2); cprintf("%c",218); /* The output 4 Corner table character */
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); /* in Save as The output 1 Line separators */
}
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) /* draw Edit A menu item */
{
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) /* draw Help A menu item 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) /* The menu control */
{
int x,y,i,B,value,flag=100,a,b;
x=wherex(); y=wherey();
if(A==F1) { drawmenu(0,flag); value=300; } /* According to File And its submenus , And display the light band in the control 1 On the submenu */
if(A==F2) { drawmenu(1,flag); value=301; } /* According to Edit And its submenus , And display the light band in the control 1 On the submenu */
if(A==F3) { drawmenu(2,flag); value=302; } /* According to Help And its submenus , And display the light band in the control 1 On the submenu */
if(A==F1||A==F2||A==F3)
{
while((B=bioskey(0))!=ESC) /* Select user key */
{
if(flag==0) flag=100;
if(value==0) value=300; /* this value Is a local variable */
if(B==UP) drawmenu(value,--flag); /* The loop goes up and down */
if(B==DOWN) drawmenu(value,++flag); /* The loop goes up and down */
if(B==LEFT) /* Cyclic selection between menu items (left shift) */
{
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)/* Loop selection between menu items (right shift) */
{
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) /* Select a submenu item of a main course item (select a item) */
{
if(value%3==0) b=5; /*File under 5 Submenu item */
if(value%3==1) b=4; /*Edit under 4 Submenu item */
if(value%3==2) b=2; /*Help under 2 Submenu item */
a=(value%3)*10+flag%b;/*a Represents the number of the selection submenu */
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);
}
/* If the button is not 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;
}
/* will head The values of the data fields in each column in the singly linked list are written to a file, the file path and file name specified by the user */
void save(Hnode *head)
{
FILE* fp;
Hnode *q;
node *p;
int count=0,x,y;
char filename[10]; /* Save file name */
q=head;
clrscr();/* Clear the screen */
printf("Enter infile name,for example [c:\\wb.txt]:");/* Enter file name format */
scanf("%s",filename); /* Enter file name */
fp=fopen(filename,"w");
if(fp==NULL) /* Failed to open file */
{
printf("\n=====>open file error!\n");
getchar();
return ;
}
do{
p=q->next; /* Point to the node Type of data */
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); /* Close this file */
return ;
}
/* Save the file as : will head The values of the data fields in each column in the singly linked list are written to a file, the file path and file name specified by the user */
void saveas(Hnode *head)
{
FILE* fp;
Hnode *q;
node *p;
int count=0,x,y;
char filename[10]; /* Save file name */
q=head;
clrscr();/* Clear the screen */
printf("Enter infile name,for example [c:\\wb.txt]:");/* Enter file name format */
scanf("%s",filename); /* Enter file name */
fp=fopen(filename,"w");
if(fp==NULL) /* Failed to open file */
{
printf("\n=====>open file error!\n");
getchar();
return ;
}
do{
p=q->next; /* Point to the node Type of data */
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); /* Close this file */
return ;
}
/* Read the file contents from any text file and save to a data structure in the form of a single linked list of rows and columns */
void opens(Hnode *Hp)
{
FILE* fp;
Hnode *q11,*q22;
node *p11,*p22,*hp;
char temp;
int count=0,flags=1;
char filename[10]; /* Save file name */
clrscr();/* Clear the screen */
printf("Enter infile name,for example [c:\\wb.txt]:");/* Enter file name format */
scanf("%s",filename); /* Enter file name */
fp=fopen(filename,"r");/* Open the file read-only, filename It has to exist */
if(fp==NULL)/* Failed to open file */
{ 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));/* new 1 Nodes in a single list of rows */
p11=(node *)malloc(sizeof(node)); /* new 1 Nodes in a single linked list of columns */
while((temp=fgetc(fp))!=10&&count<=76&&!feof(fp)) /* End of loop, in a single linked list 1 The row is processed and the new row begins */
{ p22=(node *)malloc(sizeof(node));/* new 1 Nodes in a single linked list of columns */
if(flags==1) {hp=p22;flags=0;} /*hp Saves the address of the first node in a single linked list of columns */
p22->ch=temp; p22->next=NULL;
p11->next=p22; p11=p22;
count++;
}
if(temp==10){ /* If it is a newline character, convert it to a carriage return, because in the program, it is handled as a carriage return */
p22=(node *)malloc(sizeof(node));p22->ch=13; p22->next=NULL;
p11->next=p22; p11=p22;
}
if(!feof(fp))/* If not, at the end of the file 1 The guild deals with it twice .*/
{q22->next=hp;q22->nextl=NULL; /* Associates a new column singleton with a new node in a row singleton that stores characters */
q11->nextl=q22;q11=q22;}
}
fclose(fp);
Hp=Hp->nextl;/* because Hp The data field of the node is empty, so 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)); /* Allocates memory space for the first node in a row single linked list */
q=Hhead; Hhead->nextl=NULL;
p1=p2=q->next=(node *)malloc(sizeof(node)); /* Allocates memory space for the first node in a single linked list */
p1->ch=13; p1->next=NULL;
drawmain(); /* Display main window */
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; /* Waiting for the user to press the button */
a=A=bioskey(0); /* Returns the key value of the character entered */
if(a>=32&&a<127) /* If the input is a regular character or enter key */
{
if(check(Hhead,wherey(),wherex())<=0)/* The add character operation is performed when the current position has no characters and the input is a regular character */
{
NUM++;
p2->ch=a;
putch(a);
if(NUM==76) /* Input full line continuously and generate respectively 1 New row single linked list and column single linked list nodes */
{
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 /* Continuous input less than 1 line , generate 1 A new column single linked list node */
{
p2->next=(node *)malloc(sizeof(node));
p2=p2->next;
p2->ch=13;
p2->next=NULL;
}
}
else /* The current position has characters and the input is a regular character , The insert character operation is performed */
{
x=wherex(); y=wherey();
insert(Hhead,wherey(),wherex(),a);
NUM++;
view(Hhead);
gotoxy(x,y);
}
}
/* Enter if entered */
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();
/* Move left in the text window , The current cursor is not in the window 1 column */
if((A==LEFT)&&(x!=1)) gotoxy(wherex()-1,wherey());
/* Move left in the text window , The current cursor is at the window's top 1 column */
if((A==LEFT)&&(x==1)) gotoxy(abs(judge(Hhead,wherey()-1)),wherey()-1);
/* Move right in the text window , To the right of the current cursor 1 Who has character */
if((A==RIGHT)&&check(Hhead,wherey(),wherex())>0) gotoxy(wherex()+1,wherey());
/* In the text window, move right to the descending row 1 column , If the current cursor position has no characters and is descending 1 List of characters */
if((A==RIGHT)&&check(Hhead,wherey()+1,1)!=0&&check(Hhead,y,x)<=0) gotoxy(1,wherey()+1);
/* Moves to the right */
if((A==RIGHT)&&x==76) gotoxy(1,wherey()+1);
/* Move up */
if((A==UP)&&check(Hhead,wherey()-1,wherex())!=0) gotoxy(wherex(),wherey()-1);
/* Move up */
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);
}
/* Move down */
if((A==DOWN)&&check(Hhead,wherey()+1,wherex())!=0)
gotoxy(wherex(),wherey()+1);
/* To deal with BackSpace key */
if(A==BACK) /* To deal with BackSpace key */
{
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;
}
}
/* Handle menu button F1 F2 F3*/
if((A==F1)||(A==F2)||(A==F3)||(a<32||a>127))
{ A=menuctrl(Hhead,A);
if(A==100){main();} /* The new file */
if(A==101){ /* Open the file */
Hhead=(Hnode *)malloc(sizeof(Hnode));
opens(Hhead);
getchar();clrscr();gotoxy(3,3);view(Hhead);
}
/* Save the file */
if(A==102){save(Hhead);clrscr();cprintf("save successfully!");getch();gotoxy(3,3);view(Hhead);}
/* Save the file as */
if(A==103){saveas(Hhead);clrscr();cprintf("save as successfully!");getch();gotoxy(3,3);view(Hhead);}
/* help */
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);}
}
/* To deal with DEL key , Deletes a single character at the current position */
if(A==DEL)
{
x=wherex(); y=wherey();
del(Hhead,wherey(),wherex());
view(Hhead);
gotoxy(x,y);
}
/* After processing the selected text character, press DEL The condition of the key */
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; /* this value Is a global variable */
view(Hhead);
gotoxy(x,y);
}
/* To deal with Ctrl+x The keys */
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; /* save r The maximum subscript value of a valued element of an array */
value=0; /* this value Is a global variable */
view(Hhead);
gotoxy(x,y);
}
/* To deal with Ctrl+c The keys */
if(A==Cc&&value!=0)
{
x=wherex(); y=wherey();
backup=value; value=0; /* this value Is a global variable */
view(Hhead);
gotoxy(x,y);
}
/* To deal with Ctrl+v The keys */
if(A==Cv&&backup!=0)
{
x=wherex(); y=wherey();
if(backup<0) /*Ctrl+ Right - shift key selected text, appropriate to this current position */
for(i=0;i<abs(backup);i++)
insert(Hhead,y,x+i,r[i].ch);/* Insert them one by one */
if(backup>0) /*Ctrl+ Left shift key selected text, appropriate to this current position */
for(i=0;i<backup;i++)
insert(Hhead,y,x+i,r[backup-1-i].ch);
view(Hhead);
gotoxy(x,y);
}
/* Quick preview */
if(A==F10)
{
qview(Hhead);
view(Hhead);
gotoxy(x,y);
}
/* To deal with Ctrl+ Left shift or right shift */
if(A==CL||A==CR) control(A,Hhead);
/* Displays the current column and column number */
x=wherex(); y=wherey();
window(1,1,80,25);
textcolor(0);
textbackground(7);
gotoxy(10,25); /* The first 25 Ok, the first 10 column , Prints the current line number wherey()*/
cprintf("%-3d",y);
gotoxy(24,25); /* The first 25 Ok, the first 24 column */
cprintf("%-3d",x);
window(3,3,78,23);
textcolor(10);
gotoxy(x,y);
textcolor(10);
textbackground(1);
}
}