⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 main.c

📁 一个根据软件工程课程 原创c语言编写的 中文编辑器 功能强大
💻 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 + -