A PHP Error was encountered
Severity: 8192
Message:  Function create_function() is deprecated
Filename: geshi/geshi.php
Line Number: 4698
	Backtrace:
	
		
	
		
	
		
			
			File: /home/httpd/vhosts/scratchbook.ch/geopaste.scratchbook.ch/application/libraries/geshi/geshi.php
			Line: 4698
			Function: _error_handler			
		
	
		
			
			File: /home/httpd/vhosts/scratchbook.ch/geopaste.scratchbook.ch/application/libraries/geshi/geshi.php
			Line: 4621
			Function: _optimize_regexp_list_tokens_to_string			
		
	
		
			
			File: /home/httpd/vhosts/scratchbook.ch/geopaste.scratchbook.ch/application/libraries/geshi/geshi.php
			Line: 1655
			Function: optimize_regexp_list			
		
	
		
			
			File: /home/httpd/vhosts/scratchbook.ch/geopaste.scratchbook.ch/application/libraries/geshi/geshi.php
			Line: 2029
			Function: optimize_keyword_group			
		
	
		
			
			File: /home/httpd/vhosts/scratchbook.ch/geopaste.scratchbook.ch/application/libraries/geshi/geshi.php
			Line: 2168
			Function: build_parse_cache			
		
	
		
			
			File: /home/httpd/vhosts/scratchbook.ch/geopaste.scratchbook.ch/application/libraries/Process.php
			Line: 45
			Function: parse_code			
		
	
		
			
			File: /home/httpd/vhosts/scratchbook.ch/geopaste.scratchbook.ch/application/models/Pastes.php
			Line: 517
			Function: syntax			
		
	
		
			
			File: /home/httpd/vhosts/scratchbook.ch/geopaste.scratchbook.ch/application/controllers/Main.php
			Line: 624
			Function: getPaste			
		
	
		
	
		
			
			File: /home/httpd/vhosts/scratchbook.ch/geopaste.scratchbook.ch/index.php
			Line: 315
			Function: require_once			
		
	
 
A PHP Error was encountered
Severity: Warning
Message:  Cannot modify header information - headers already sent by (output started at /home/httpd/vhosts/scratchbook.ch/geopaste.scratchbook.ch/system/core/Exceptions.php:271)
Filename: view/download.php
Line Number: 2
	Backtrace:
	
		
	
		
	
		
	
		
			
			File: /home/httpd/vhosts/scratchbook.ch/geopaste.scratchbook.ch/themes/geocities/views/view/download.php
			Line: 2
			Function: header			
		
	
		
			
			File: /home/httpd/vhosts/scratchbook.ch/geopaste.scratchbook.ch/application/core/MY_Loader.php
			Line: 173
			Function: include			
		
	
		
			
			File: /home/httpd/vhosts/scratchbook.ch/geopaste.scratchbook.ch/application/core/MY_Loader.php
			Line: 43
			Function: _ci_load			
		
	
		
			
			File: /home/httpd/vhosts/scratchbook.ch/geopaste.scratchbook.ch/application/controllers/Main.php
			Line: 625
			Function: view			
		
	
		
	
		
			
			File: /home/httpd/vhosts/scratchbook.ch/geopaste.scratchbook.ch/index.php
			Line: 315
			Function: require_once			
		
	
 
A PHP Error was encountered
Severity: Warning
Message:  Cannot modify header information - headers already sent by (output started at /home/httpd/vhosts/scratchbook.ch/geopaste.scratchbook.ch/system/core/Exceptions.php:271)
Filename: view/download.php
Line Number: 3
	Backtrace:
	
		
	
		
	
		
	
		
			
			File: /home/httpd/vhosts/scratchbook.ch/geopaste.scratchbook.ch/themes/geocities/views/view/download.php
			Line: 3
			Function: header			
		
	
		
			
			File: /home/httpd/vhosts/scratchbook.ch/geopaste.scratchbook.ch/application/core/MY_Loader.php
			Line: 173
			Function: include			
		
	
		
			
			File: /home/httpd/vhosts/scratchbook.ch/geopaste.scratchbook.ch/application/core/MY_Loader.php
			Line: 43
			Function: _ci_load			
		
	
		
			
			File: /home/httpd/vhosts/scratchbook.ch/geopaste.scratchbook.ch/application/controllers/Main.php
			Line: 625
			Function: view			
		
	
		
	
		
			
			File: /home/httpd/vhosts/scratchbook.ch/geopaste.scratchbook.ch/index.php
			Line: 315
			Function: require_once			
		
	
 //本代码和所有注释由PYZ倾情编写
#include 
#include 
#include 
#include 
#define char_num 1000 //一行的字符个数
using namespace std;
struct Node //节点,一个节点存一行的内容
{
	char content[char_num] = {0}; //一行的内容字符数组
	int LineNum;//行号
	Node *next = nullptr;//后以个节点
	Node *priv = nullptr;//前一个节点
};
class TextArea //包装节点的类;相当于一个TextArea类的对象就保存若干行的文字;但本程序实际上只需要存入一个文件的文字,也可以不用包装起来
{
public:
	int LineCount = 0;//总行数
	int CharCount = 0;//总字符数
	Node *last = nullptr; //最后一个节点,也即最后一行
	Node *first = nullptr;//第一个节点,也即第一行
	Node *head = nullptr; //头节点,其content为空,next指针指向第一个节点
	TextArea() = default; //默认构造函数
};
void PrintNodes(Node *);//打印所有节点(此处为函数声明,定义在后面)
void PrintNode(Node *);//打印单个节点
void DelNode(int, TextArea &);//删除单个节点
Node *GoTo(int, TextArea &); //跳转到特定一行
int main()
{
	TextArea text1;	//创建一个对象
	text1.head = new Node; //创建一个头节点,它的next指向第一个节点,它不存放其他内容
	text1.head->LineNum = -1;
	char *InFileName = new char[100]; //存放输入文件名
	char *OutFileName = new char[100]; //存放输出文件名
	cout << "请输入欲输入的文件名(不能包含空格):";
	cin >> InFileName;
	cout << "请输入欲输出的文件名(不能包含空格):";
	cin >> OutFileName;
	fstream InFile; //创建fstream文件流对象
	InFile.open(InFileName, fstream::in | fstream::out); //打开输入文件
	if (!InFile.is_open())	//如果文件成功打开,则InFile.is_open()=1,此处判断是否未成功打开
	{
		cout << "文件打开失败!是否要新建该文件?Y/N" << endl;
		char YN;
		cin >> YN;
		if (YN >= 'A' && YN <= 'Z')
		{
			YN += 'a' - 'A'; //大写转小写
		}
		if (YN == 'y')
		{
			InFile.open(InFileName, fstream::in | fstream::out | fstream::trunc); //创建文件
		}
		else
			exit(1); //非正常退出
	}
	Node *CurNode = new Node;
	text1.head->next = CurNode;
	if (!InFile.eof()) //如果文件没到末尾
	{
		InFile.getline(CurNode->content, char_num - 1); //先读一行进来,因为文件至少得有一行(即使是空的)【我是这样认为的】
		text1.CharCount += strlen(CurNode->content);	//字符计数
		text1.LineCount++;	//行数计数
		CurNode->LineNum = text1.LineCount;	//存入行号
	}
	while (!InFile.eof()) //如果文件没到末尾,则一直循环一行一行读取
	{
		Node *TempNode = CurNode;
		CurNode->next = new Node;
		CurNode = CurNode->next;
		CurNode->priv = TempNode; //创建新节点完毕
		text1.LineCount++;
		CurNode->LineNum = text1.LineCount;
		InFile.getline(CurNode->content, char_num - 1);//读一行内容并存入content(不含回车)
		text1.CharCount += strlen(CurNode->content);
		//写入新节点完毕
	}
	InFile.close();//关闭文件
	text1.last = CurNode;	//存下最后一个节点的指针
	text1.first = text1.head->next; //存下第一个节点的指针
	char action;
	Node *CurNode2 = nullptr; //当前操作的节点,现在还未开始,故为空
	Node *temp = nullptr; //供之后可重复使用的temp节点
	int CurLine = 0; //当前操作的行号,0行不存在
	while (1)
	{
		cout << "请输入动作(输入H 或 h以显示帮助 ) : ";
		cin >> action;
		getchar(); //吃掉回车,免得出问题
		if (action >= 'A' && action <= 'Z')
		{
			action += 'a' - 'A'; //大写转小写
		}
		switch (action)
		{
		case 'h': //Help
			cout << "以下是操作列表(不区分大小写)" << endl;
			cout << "V:查看整个文件内容" << endl;
			cout << "F:转到第一行" << endl;
			cout << "L:转到最后一行" << endl;
			cout << "N:转到下一行" << endl;
			cout << "P:转到上一行" << endl;
			cout << "G:转到特定的某行" << endl;
			cout << "D:删除特定某行" << endl;
			cout << "O:覆盖当前行内容" << endl;
			cout << "S:在当前行查找子串" << endl;
			cout << "R:在当前行替换子串" << endl;
			cout << "T:显示统计信息" << endl;
			cout << "C:保存文件" << endl;
			cout << "E:退出编辑器" << endl;
			break;
		case 'v': //View The Whole File
			PrintNodes(text1.head);
			break;
		case 'g': //Goto A Line
			int GoNum;
			cout << "请输入要跳转的行数:";
			if (!(cin >> GoNum))
			{
				cout << "输入错误!" << endl;
				break;
			}
			temp = GoTo(GoNum, text1);
			if (temp == nullptr)
			{
				cout << "没有这一行" << endl;
				break;
			}
			CurNode2 = temp;
			CurLine = CurNode2->LineNum;
			PrintNode(CurNode2);
			temp = nullptr; //temp用完后重新置空
			break;
		case 'e': //Exit
			exit(0);
			break;
		case 'f': //Go To First Line
			CurLine = 1;
			CurNode2 = GoTo(1, text1);
			PrintNode(GoTo(1, text1));
			break;
		case 'l': //Go To Last Line
			CurLine = text1.LineCount;
			CurNode2 = GoTo(text1.LineCount, text1);
			PrintNode(CurNode2);
			break;
		case 'n': //Go To Next Line
			if (CurLine == 0)//因为行号是从第一行开始,所以第一次要单独判断一下,因为此时CurNode2=nullptr,没办法用
			{
				CurLine = 1;
				CurNode2 = GoTo(1, text1);
				PrintNode(GoTo(1, text1));
				break;
			}
			if (CurLine == text1.LineCount)
			{
				cout << "已是最后一行!" << endl;
				break;
			}
			CurLine++;
			CurNode2 = CurNode2->next;
			PrintNode(CurNode2);
			break;
		case 'p': //Go To Previous Line
			if (CurLine == 1 || CurLine == 0)
			{
				cout << "已是第一行!" << endl;
				break;
			}
			CurLine--;
			CurNode2 = CurNode2->priv;
			PrintNode(CurNode2);
			break;
		case 'd': //Delete A Line
			int DelNum;
			cout << "请输入要删除的行号:";
			cin >> DelNum;
			if (DelNum < CurLine) //要删除的行在当前行之前(如果要删除的在当前行之后,那么无需特别动作,只需执行删除操作即可
			{
				CurLine--;//当前行号需要减一,但当然行指针不变,依旧指向当前行
			}
			else if (DelNum == CurLine) //要删除的行跟当前行相同
			{
				if (CurNode2->next) //如果Curnode2有next,那么就指向它;也即是当前行指针指向被删除行的下一行
				{
					CurNode2 = CurNode2->next;
				}
				else //如果CurNode2没有next(也即它是最后一行)
				{
					if (CurNode2->priv) //有priv
					{
						CurLine--;
						CurNode2 = CurNode2->priv;
					}
					else //没有next,也没有priv,证明它是第一行
					{
						//CurLine和CurNode2不变
					}
				}
			}
			DelNode(DelNum, text1);//调用删除函数进行进一步操作
			break;
		case 'i': //Insert A Line After Current Line
			if (CurNode2) //CurNode2!=nullptr;也即此刻不是第0行
			{
				temp = CurNode2;
				while (temp->next) //把当前行之后的所有行的行号都加一(小技巧,一般这种形式的while循环,我就读作while(temp有next))
				{
					temp = temp->next;
					temp->LineNum++;
				}
				temp = new Node;
				temp->LineNum = CurLine + 1; //插入的新行的行号为当前行号加一
				if (CurNode2->next)
				{
					temp->priv = CurNode2;
					temp->next = CurNode2->next;
					CurNode2->next->priv = temp;
					CurNode2->next = temp;
				}
				else //CurNode2无next,即为最后一行,那么新插入的行成为最后一行
				{
					CurNode2->next = temp;
					temp->priv = CurNode2;
					temp->next = nullptr;//最后一行没有下一行
				}
				text1.LineCount++; //总行数加一
				cout << "请键入增加行的内容:";
				fgets(temp->content, char_num - 1, stdin);
				if (temp->content[strlen(temp->content) - 1] == '\n') //fgets会连同空格和回车一起存进content,但我们不要回车,故用此法去掉回车
					temp->content[strlen(temp->content) - 1] = 0;
				CurLine++; 
				CurNode2 = temp; //当前行指针指向新插入的行
				cout << "插入成功!" << endl;
				temp = nullptr;
				break;
			}
			cout << "错误,目前未处于任何一行!" << endl;//进入这行语句,证明CurNode2为空
			break;
		case 'o': //Override Current Line
			if (CurNode2)
			{
				memset(CurNode2->content, 0, char_num);//清空本行原有内容
				cout << "请输入想要将本行替换为的内容:";
				fgets(CurNode2->content, char_num - 1, stdin);
				if (CurNode2->content[strlen(CurNode2->content) - 1] == '\n')
					CurNode2->content[strlen(CurNode2->content) - 1] = 0;
				cout << "替换成功!" << endl;
				break;
			}
			cout << "错误,目前未处于任何一行!" << endl;
			break;
		case 's': //Search For A SubString In Current Line
			if (CurNode2)
			{
				cout << "当前行内容:" << endl;
				PrintNode(CurNode2);//先打印一下本行内容
				cout << "请输入想要在本行查找的内容:";
				char SearchChar[char_num] = {0};//存想要找的子串
				fgets(SearchChar, char_num - 1, stdin);//输入想要找的子串
				if (SearchChar[strlen(SearchChar) - 1] == '\n')//去除回车
					SearchChar[strlen(SearchChar) - 1] = 0;
				char *Place = strstr(CurNode2->content, SearchChar); //返回子串第一次出现位置的内存地址
				int PlaceInt = Place - CurNode2->content; //转换成下标(数组名就是数组第一个元素的首地址,这样相当于算出来偏移量)
				if (PlaceInt < 0)
				{
					cout << "未找到该子串!" << endl;
					break;
				}
				cout << "子串第一次出现位置为:" << PlaceInt << endl;
				break;
			}
			cout << "错误,目前未处于任何一行!" << endl;
			break;
		case 'r': //Repalce A SubString In Current Line
			if (CurNode2)
			{
				cout << "当前行内容:" << endl;
				PrintNode(CurNode2);
				cout << "请输入想要在本行要替换的内容:";
				char ToReplaceChar[char_num] = {0};
				fgets(ToReplaceChar, char_num - 1, stdin);
				if (ToReplaceChar[strlen(ToReplaceChar) - 1] == '\n')
					ToReplaceChar[strlen(ToReplaceChar) - 1] = 0;
				char *Place = strstr(CurNode2->content, ToReplaceChar);
				int PlaceInt = Place - CurNode2->content;//首先先查找要替换的内容
				if (PlaceInt < 0)
				{
					cout << "未找到要替换的内容!" << endl;
					break;
				}
				cout << "请输入,将目标替换成:";
				char ReplaceChar[char_num] = {0};
				fgets(ReplaceChar, char_num - 1, stdin);
				if (ReplaceChar[strlen(ReplaceChar) - 1] == '\n')
					ReplaceChar[strlen(ReplaceChar) - 1] = 0;
				char FinalChar[char_num] = {0};//存替换完之后整行的内容
				int FCCount = 0;//FinalChar的计数器
				for (int i = 0; i < strlen(CurNode2->content); i++)//将content的内容一个一个赋给FinalChar
				{
					if (i == PlaceInt)//当到了要替换的位置
					{
						for (int j = 0; j < strlen(ReplaceChar); j++)//转而赋值替换后的字符
						{
							FinalChar[FCCount++] = ReplaceChar[j];
						}
						i += strlen(ToReplaceChar) - 1;//然后把i的值加上被替换子串的长度(由于是下标,故减一),实现跳过这个子串
						continue;
					}
					else
					{
						FinalChar[FCCount++] = CurNode2->content[i];
					}
				}
				strcpy(CurNode2->content, FinalChar);//最后把FinalChar复制给content
				break;
			}
			cout << "错误,目前未处于任何一行!" << endl;
			break;
		case 't': //Show The Whole Line Number And Char Number(拼音"统")
			cout << "总行数:" << text1.LineCount << " 行 \t"
				 << "总字符数(含空格):" << text1.CharCount << endl;
			break;
		case 'c': //Save File(拼音"存")
			fstream OutFile(OutFileName, fstream::out);
			temp = text1.head;
			while (temp->next)
			{
				temp = temp->next;
				OutFile << temp->content;//一行一行地写入文件
				if (temp->next != nullptr)//如果不是最后一行,那么就在行末加个回车
					OutFile << "\n";
			}
			OutFile.close();
			break;
		}
	}
	cout << "==============ALL DONE=================";
}
void PrintNodes(Node *head)//打印所有节点,需要传入一个头节点的指针
{
	if (head->next)
	{
		Node *CurNode = head->next;
		cout << CurNode->LineNum << " |";//先打印行号,再打印内容
		if (CurNode->content[0])//判断一下内容的第一个字符是不是'\0',即空字符,如果是,则说明此行内容为空,输出一个空行;此处if判断如果不是空字符,则进入if
		{
			cout << CurNode->content;
		}
		cout << endl;
		while (CurNode->next) //循环打印剩下的所有节点
		{
			CurNode = CurNode->next;
			cout << CurNode->LineNum << " |" << CurNode->content << endl;
		}
	}
}
void PrintNode(Node *Line)//传入单个节点并打印
{
	cout << Line->LineNum << " |";
	if (Line->content[0])
	{
		cout << Line->content;
	}
	cout << endl;
}
Node *GoTo(int GoNum, TextArea &TA)//跳转到特定的一行,传入要跳转的行号和TextArea的引用,用于调用head等成员;返回要跳转到的行的指针
{
	if (TA.head->next)
	{
		Node *CurNode = TA.head->next;
		if (CurNode->LineNum == GoNum)//判断行号是否匹配
		{
			return CurNode;
		}
		while (CurNode->next)//遍历判断行号是否匹配
		{
			CurNode = CurNode->next;
			if (CurNode->LineNum == GoNum)
			{
				return CurNode;
			}
		}
	}
	return nullptr; //如果程序执行到此处,则证明以上步骤都没有匹配到对应的行,说明不存在这一行,返回空
	//写到这里,我觉得自己是个傻子,为什么不直接先判断一下行号是否小于1或者大于最后一行的行号呢?这样就能直接判断出要跳转的行存不存在了
}
void DelNode(int DelNum, TextArea &TA)//删除特定行
{
	if (DelNum < 1 || DelNum > TA.LineCount)//这里学乖了,先判断一下要删除的行是不在范围内
	{
		cout << "没有这一行!" << endl;
		return;
	}
	Node *CurNode = GoTo(DelNum, TA);//存在则先跳转到要删除的那行
	if (CurNode->next)//如果要删除的行有next
	{
		if (CurNode->priv)//如果它同时还有priv,则证明它处于两行中间
		{
			CurNode->priv->next = CurNode->next;
			CurNode->next->priv = CurNode->priv;//移动它上下两行内部的指针
			Node *Temp = CurNode;
			while (CurNode->next)//把它后面行的行号都减一
			{
				CurNode = CurNode->next;
				CurNode->LineNum--;
			}
			delete Temp;
			TA.LineCount--;//总行数减一
			cout << "删除成功!" << endl;
			return;
		}
		else//没有priv,则说明它是第一行
		{
			TA.head->next = CurNode->next;//要删除第一行,就得先移动头节点的next
			CurNode->next->priv = nullptr;//把它的下一行(它的下一行即将成为第一行)的priv置空
			TA.first = CurNode->next;//第一行的指针指向新的第一行
			Node *Temp = CurNode;
			while (CurNode->next)//行号减一
			{
				CurNode = CurNode->next;
				CurNode->LineNum--;
			}
			delete Temp;
			TA.LineCount--;//总行数减一
			cout << "删除成功!" << endl;
			return;
		}
	}
	else//要删除的行没有next,证明它是最后一行
	{
		if (CurNode->priv)//如果它有priv,证明它不是"既是最后一行又是第一行"
		{
			CurNode->priv->next = nullptr;//只需要把它的前一行的next置空
			delete CurNode;
			TA.LineCount--;//总行数减一
			cout << "删除成功!" << endl;
			return;
		}
		else//此处既没有next也没有priv,那它就是唯一的一行,所以不能删掉
		{
			memset(CurNode->content, 0, char_num);//只需清空内容即可
			cout << "删除成功!" << endl;
			return;
		}
	}
}