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);
    }
 }


Related articles: