📄 main.c
字号:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <stdio.h>
#define LINESIZE 100
#define TEXTSIZE 100
#define ORGFREE 100
typedef struct text
{
struct text *pPre;
struct text *pNext;
char lineBuf[LINESIZE];
};
typedef struct text _TEXT, *pTEXT;
pTEXT TPTR,
BPTR,
KPTR,
QPTR,
FPTR,
XPTR,
YPTR,
SPTR;
char BUF[LINESIZE],
IN[LINESIZE], //i/o buffer.
// CHAR[LINESIZE], //i/o buffer.
REP[LINESIZE], //stores the replace chars
TMP[LINESIZE], //temp buffer
MAT[LINESIZE], //stores the matching chars
NUMD[4] ; //stores the chars that will be turned into a number.
int K, //indicate position in REP
I, //indicate position in IN
J, //indicate position in MAT
M, //indicate position in NUMD
NUM, //stores operand data
IND, //0--Mode edit 1,2--Mode input(no lines yet,at leat one)
CHG, //switch var
ERR, //switch var
CRT, //get data from num,
CMP; //swithc var
char CHAR;
_TEXT TEXT[TEXTSIZE];
//以上是所有要用的数据结构
void INIT();
void READ_LINE();
void WRITE_LINE();
void INPUT();
void GO_EDIT();
void CONNECT();
void INSERT_CHAIN();
void TOP(); //
void ENTER(); //go to Mode input
void UP();
int GET_NUMBER(); //get data from Edit command,puts it in numd.def 1
void CONVERT(); //convert string to int.
void NEXT();
void LIST(); //outputs N lines form the current line num.
void DELETE(); //delete N lines form the curent line num,put into free link.
void DELETE_LINK(); //called by delete and store.
void COPY(); //copy N lines form the cur line num,put into free,then to work link
void COPY_LINK(); //called by copy
void STORE(); //delete N lines form the current line num,put into work link tail.
void INSERT(); //inserts all text in work links under the cur line.
void FIND(); //scan text from the next line,set pointer to line where string first found.
int GET_STRING1(); //get first string from command,stores in MAT.
void COMP(); //compare string in IN and MAT,set CMP to 1 or 0.
void REPLACE(); //replaces string1 from cur to N lines with string2
int GET_STRING2(); //get second parameter from command.
//以上是所有的函数的声明
void main()
{
int flag = 1; //run 1,0 exit
INIT();
while(flag)
{
READ_LINE();
I = 0;
if(IND !=0) //mode input
INPUT();
else
{
CHAR = IN[I];
switch(CHAR)
{
case 'T': TOP(); break;
case 'U': { I+=1; UP();} break;
case 'N': { I+=1; NEXT();} break;
case 'E': ENTER(); break;
case 'L': { I+=1; LIST();} break;
case 'D': { I+=1; DELETE();} break;
case 'R': { I+=1; REPLACE();}break;
case 'F': { I+=1; FIND();} break;
case 'I': INSERT(); break;
case 'C': { I+=1; COPY();} break;
case 'S': { I+=1; STORE();} break;
case 'Q': flag = 0; break;
default:
{
strcpy(IN,"?!\0");
WRITE_LINE();
}
}
}
}
}
void INIT()
{
int i = 0; //a iterator
CMP = CHG = ERR = 0;
IND =1; //?????
strcpy(IN,"INPUT"); //?????
WRITE_LINE();
BPTR = TPTR = 0; //THERE IS NO REGULAR TEXT
KPTR = QPTR = 0; //NO WORK LINK
for(i=1; i< TEXTSIZE-1; i++)
{
TEXT[i].pPre = &TEXT[i-1];
TEXT[i].pNext = &TEXT[i+1];
}
TEXT[0].pPre = NULL;
TEXT[0].pNext = &TEXT[1];
TEXT[TEXTSIZE-1].pNext = NULL;
TEXT[TEXTSIZE-1].pPre = &TEXT[TEXTSIZE-2];
FPTR = &TEXT[0]; //link all to free link.
}
void READ_LINE()
{
//unsigned int i;
memset(IN,' ',sizeof(IN));
I = 0;
while((BUF[0] = getchar()) != 10)
{
if(BUF[0] < 0) //is a chinese char
BUF[1] = getchar();
switch (BUF[0])
{
case '@': //delete previous char
{
if(I != 0)
{
if(IN[I-1] < 0) //is a chinese char
{I = I -2 ;
IN[I] = IN[I+1] = ' '; //set to space
}
else
{ //is a ascII
I = I-1;
IN[I] = ' '; //set to space.
}
}
}break;
case '#'://delete a line
{
memset(IN,' ',sizeof(IN));
I = 0;
}break;
case '!': //change line.
{
if(I == 0) //is the first one on a new line.accept
{
IN[I] = BUF[0];
I++;
}
else
return;
}break;
default: //common chars ,store them in IN
{
if(BUF[0] < 0 && I < LINESIZE) //is a chinese char
{
IN[I] = BUF[0];
I += 1;
IN[I] = BUF[1];
I += 1;
}
else if(BUF[0] >= 0 && I < LINESIZE)
{
IN[I] = BUF[0];
I += 1;
}
else //has input too many chars
{
strcpy(TMP,IN);
strcpy(IN,"?!\0");
WRITE_LINE();
strcpy(IN,TMP);
return;
}
}
}
}
IN[I] = 0;
}
void WRITE_LINE()
{
I = 0;
while(IN[I])
{
BUF[I] = IN[I];
putchar(BUF[I]);
I += 1;
}
BUF[0] = 10; //change line
putchar(BUF[0]);
}
void INPUT()
{
//assert(I == 0);
CHAR = IN[I];
if(IND ==1) //NO TEXT YET
{
if(CHAR == '!')
GO_EDIT(); //go to mode edit
else
{
if(FPTR == NULL) //no free link .
{
strcpy(IN,"NOFREE\0");
WRITE_LINE();
}
else
{
XPTR = FPTR;
memcpy(XPTR->lineBuf, IN,sizeof(IN));
//FPTR = FPTR->pNext;
IND = 2;
}
}
}
else //at least one more lines.
{
if(CHAR == '!') // move from free link to regular text.and to mode edit
{
CONNECT();
INSERT_CHAIN();
GO_EDIT();
}
else
{
if(FPTR == NULL) //No more free link
{
CONNECT();
INSERT_CHAIN();
strcpy(IN,"NOFREE\0");
WRITE_LINE();
GO_EDIT();
}
else //put it into the next item of free link.
{
XPTR = XPTR->pNext;
strcpy(XPTR->lineBuf, IN);
}
}
}
}
void GO_EDIT()
{
IND = 0;
strcpy(IN,"EDIT\0");
WRITE_LINE();
}
void CONNECT()
{
YPTR = FPTR; //start pos of text
FPTR = XPTR->pNext;
if(FPTR != 0)
{
FPTR->pPre = NULL;
}
}
void INSERT_CHAIN() //YPTR POINTS TO FIRST,XPTR POINTS TO LAST,
{
if(BPTR == 0) //sptr --insert pointer
{
if(TPTR == 0)
{
SPTR = TPTR;
}
else
{
TPTR->pPre = XPTR;
SPTR = TPTR;
}
TPTR = YPTR;
}
else //BPTR NOT NULL
{
SPTR = BPTR->pNext;
YPTR->pPre = BPTR;
BPTR->pNext = YPTR;
}
if (SPTR != 0)
{
SPTR->pPre = XPTR;
}
XPTR->pNext = SPTR;
BPTR = XPTR;
}
void TOP()
{
BPTR = 0;
}
void ENTER() //go to Mode input
{
IND = 1;
strcpy(IN,"INPUT");
WRITE_LINE();
}
void UP()
{
if(GET_NUMBER() == 1) //error!
return;
CRT = NUM; //call get_number to get a num and put it in NUM.
if(TPTR == 0)
{
strcpy(IN,"NOTEXT");
WRITE_LINE();
return;
}
if(BPTR == 0)
{
strcpy(IN,"TOP");
WRITE_LINE();
return;
}
while(NUM)
{
BPTR = BPTR->pPre;
CRT = CRT-1;
if(BPTR == 0)
{
strcpy(IN,"TOP");
WRITE_LINE();
return;
}
}
strcpy(IN,BPTR->lineBuf);
WRITE_LINE();
}
int GET_NUMBER()
{
ERR = 0;
if(IN[I] == ' ') // should be a space.
I = I + 1;
else
{
strcpy(IN,"?!\0");
WRITE_LINE();
return 1;
}
memset(NUMD,0,sizeof(NUMD));
while( !(strlen(NUMD) == 4 || I>LINESIZE) )
{
if(!isdigit(IN[I]))
break;
else
{
NUMD[strlen(NUMD)] = IN[I];
I = I+1;
}
}
if( I<LINESIZE && IN[I] ) //NOW IN[I] should be a NULL
{
strcpy(IN,"?!\0");
WRITE_LINE();
return 1;
}
CONVERT();
if(ERR == 1)
{
strcpy(IN,"?!\0");
WRITE_LINE();
return 1;
}
else
return 0;
}
void CONVERT()
{
if(!NUMD[0])
NUM = 1;
else
NUM = atoi(NUMD);
if(NUM == 0)
ERR = 1;
}
void NEXT()
{
if (GET_NUMBER() == 1)
return;
CRT = NUM;
if(BPTR == 0)
{
if(TPTR == 0)
{
strcpy(IN,"NOTEXT");
WRITE_LINE();
return;
}
else
{
BPTR = TPTR;
CRT = CRT-1;
}
}
while(CRT)
{
if(BPTR->pNext == 0)
{
strcpy(IN,"EOF");
WRITE_LINE();
return;
}
BPTR = BPTR->pNext;
CRT = CRT-1;
}
strcpy(IN,BPTR->lineBuf);
WRITE_LINE();
}
void LIST()
{
if(GET_NUMBER() ==1 )
return;
CRT = NUM;
if(BPTR == 0)
{
if(TPTR == 0) //NO TEXT .
{
strcpy(IN,"NOTEXT");
WRITE_LINE();
return;
}
else
BPTR = TPTR;
}
strcpy(IN,BPTR->lineBuf);
CRT = CRT-1;
WRITE_LINE();
while(CRT)
{
if(BPTR->pNext == 0)
{
strcpy(IN,"EOF");
WRITE_LINE();
return;
}
BPTR = BPTR->pNext;
strcpy(IN,BPTR->lineBuf);
CRT = CRT - 1;
WRITE_LINE();
}
}
void DELETE()
{
if(GET_NUMBER() == 1)
return;
CRT = NUM;
if(BPTR == 0)
{
if(TPTR == 0)
{
strcpy(IN,"NOTEXT\0");
WRITE_LINE();
return;
}
BPTR = TPTR;
}
DELETE_LINK(); //XPTR --LAST YPTR --FIRST LINE.
XPTR->pNext = FPTR;
if(FPTR != 0)
{
FPTR->pPre = XPTR;
}
YPTR->pPre = 0;
YPTR = FPTR;
}
void DELETE_LINK() //XPTR --LAST YPTR --FIRST LINE.
{
YPTR = BPTR;
XPTR = BPTR;
CRT = CRT-1;
while(CRT > 0 && XPTR->pNext != 0)
{
XPTR = XPTR->pNext;
CRT = CRT - 1;
}
if(XPTR->pNext == 0)
{
if(CRT > 0)
{
strcpy(IN,"EOF");
WRITE_LINE();
}
if(YPTR->pPre == 0)
{
TPTR = 0;
BPTR = 0;
}
else
{
BPTR = YPTR->pPre;
BPTR->pNext =0;
}
}
else
{
BPTR = XPTR->pNext ;
if(YPTR->pPre == 0)
{
TPTR = BPTR;
BPTR->pPre = 0;
}
else
{
SPTR = YPTR->pPre;
SPTR->pNext = BPTR;
BPTR->pPre = SPTR;
}
}
}
void COPY()
{
if(GET_NUMBER()==1)
return;
CRT = NUM;
if(BPTR == 0)
{
if(TPTR == 0)
{
strcpy(IN,"NOTEXT");
WRITE_LINE();
return;
}
else
{
BPTR = TPTR;
}
}
YPTR = BPTR;
XPTR = BPTR;
SPTR = FPTR;
if(SPTR == 0)
{
strcpy(IN,"NOFREE");
WRITE_LINE();
return;
}
COPY_LINK();
if(SPTR == 0) //not enough free link,ignore this command.
return;
//FPTR FREE FIRST,SPTR LAST.KPTR WORK FIRST,QPTR LAST.
if(QPTR == 0) //work link is empty KPTR IS HEAD.QPTR IS TAIL
{
KPTR = FPTR;
}
else //work link is not empty
{
FPTR->pPre = QPTR;
QPTR->pNext = FPTR;
}
QPTR = SPTR;
FPTR = SPTR->pNext;
QPTR->pNext = NULL;
if(FPTR != 0)
{
FPTR->pPre = NULL;
}
}
void COPY_LINK()
{
while(CRT)
{
strcpy(SPTR->lineBuf,XPTR->lineBuf);
CRT = CRT-1;
if(CRT != 0 && XPTR->pNext != 0)
{
XPTR = XPTR->pNext;
}
else
break;
if(SPTR->pNext == 0) //FREE LINK IS NOW EMPTY
{
strcpy(IN,"NOFREE");
SPTR = 0;
WRITE_LINE();
return;
}
SPTR = SPTR->pNext;
}
if(XPTR->pNext == 0) //came to the text 's tail.
{
if(CRT >0)
{
strcpy(IN,"EOF");
WRITE_LINE();
}
BPTR = XPTR;
}
else
BPTR = XPTR->pNext;
}
void STORE()
{
if(GET_NUMBER())
return;
CRT = NUM;
if(BPTR == 0)
{
if(TPTR == 0)
{
strcpy(IN,"NOTEXT");
WRITE_LINE();
return;
}
else
{
BPTR = TPTR;
}
}
DELETE_LINK();
YPTR->pPre = QPTR; //QPTR POINTS TO THE TAIL OF WORK LINK
if(QPTR == 0) //work link is empty
{
KPTR = YPTR;
}
else
{
QPTR->pNext = YPTR;
}
XPTR->pNext = 0;
QPTR = XPTR;
}
void INSERT()
{
if(KPTR == 0) //work link is empty.
return;
YPTR = KPTR;
XPTR = QPTR;
KPTR = QPTR = 0;
INSERT_CHAIN();
}
void FIND() //scan from current line's next line
{
if(GET_STRING1() == 1)
return;
if(TPTR == 0)
{
strcpy(IN,"NOTEXT");
WRITE_LINE();
return;
}
if(BPTR == 0)
BPTR = TPTR;
else if(BPTR->pNext != 0)
{
BPTR = BPTR->pNext;
}
else
{
strcpy(IN,"EOF");
WRITE_LINE();
return;
}
while(1)
{
strcpy(IN,BPTR->lineBuf);
I = 0;
while(1)
{
COMP();
if(CMP == 1)
{
CMP = 0;
WRITE_LINE();
return;
}
else
{
I = I+1;
}
if(I>LINESIZE)
break;
}
if(BPTR->pNext != NULL)
BPTR = BPTR->pNext;
else
break;
}
strcpy(IN,"EOF");
WRITE_LINE();
}
int GET_STRING1()
{
if(IN[I] != ' ') //is not a space
{
strcpy(IN,"?!\0");
WRITE_LINE();
return 1;
}
I += 1;
if(IN[I] != '/')
{
strcpy(IN,"?!\0");
WRITE_LINE();
return 1;
}
I += 1;
if(IN[I] == '/')
{
strcpy(IN,"?!\0");
WRITE_LINE();
return 1;
}
J = 1;
while(IN[I] != '/') //find another /,compelete.
{
if (I == LINESIZE) //has left out another /?
{
strcpy(IN,"?!\0");
WRITE_LINE();
return 1;
}
else //move to next char
{
I = I+1;
J = J+1;
}
}
strncpy(MAT,IN+I-J+1,J-1);
MAT[J-1] = 0;
return 0;
}
void COMP() //compare IN from I with MAt
{
int tmp = I; //stores orginal I
unsigned i = 0;
J = 0;
if((unsigned)(LINESIZE - I +1) < strlen(MAT))
{
CMP = 0;
return;
}
else
for(i = 0; i<strlen(MAT); i++)
{
if(IN[tmp] != MAT[J])
{
CMP = 0;
return;
}
tmp ++;
J ++;
}
CMP = 1;
}
/*******************************
string1 is in mat.J
string2 is in rep.K
N is in NUM.
********************************/
void REPLACE() //from current to +N,replace string1 with string 2.
{
int tmpLen;
char tmp[100];
if (GET_STRING1() == 1)
return;
if( GET_STRING2() == 1)
return;
if( GET_NUMBER() ==1)
return;
if(BPTR == 0)
{
if(TPTR == 0)
{
strcpy(IN,"NOTEXT");
WRITE_LINE();
return;
}
else
BPTR = TPTR;
}
CRT = NUM; //A counter.
for(;CRT;CRT--)
{
CHG = 0;
strcpy(IN,BPTR->lineBuf);
I = 0;
while(IN[I])//I<=LINESIZE)
{
COMP();
if(CMP == 1) //FIND ONE MATCH.
{
CMP = 0;
CHG = 1;
strcpy(tmp,IN);
memset(IN,' ',sizeof(IN));
memcpy(IN,tmp,I);
tmpLen = strlen(REP);
memcpy(IN+I,REP,tmpLen);
memcpy(IN+I+tmpLen,tmp+I+strlen(MAT),strlen(IN)-I-strlen(MAT)+1);
IN[strlen(tmp)-strlen(MAT)+strlen(REP)] = 0;
}
I++;
}
if(CHG)
{
strcpy(BPTR->lineBuf,IN);
WRITE_LINE();
//CRT--;
//if(CRT == 0)
// return;
}
if(BPTR->pNext == NULL)
{
strcpy(IN,"EOF");
WRITE_LINE();
return;
}
BPTR = BPTR->pNext;
}
}
int GET_STRING2()
{
I++;
if(IN[I] == '/')
{
strcpy(IN,"?!\0");
WRITE_LINE();
return 1;
}
K = 0;
while(IN[I] != '/')
{
if(I == LINESIZE)
{
strcpy(IN,"?!\0");
WRITE_LINE();
return 1;
}
I ++;
K++; //a length counter
}
memcpy(REP,IN+I-K,K);
REP[K] = 0;
I++; //I points to the char after the third '/'.
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -