#include <iostream>
#include <list>
#include <fstream>
#include <vector>
#include <string>
using namespace std;
class Editor
{
public:
//后置条件:编辑器为空。
Editor();
/* 如果line为合法命令,则该命令被执行,执行结果被返回。若line是插入的文本行,则该文本行被插入并返回结果;否则,返回非法命令错误。*/
string parse(const string& line);
protected:
/*如果line不是很长,则将其插入编辑器,并返回一个空行;否则,返回错误信息。*/
string insert_command(const string& line);
/*后置条件:如有可能,删除第k至第m行,并返回一个空行;否则,返回错误信息。 */
string delete_command(int k, int m);
/*后置条件:如有可能,第m行成为当前行,并返回一个空行;否则,返回错误信息。 */
string line_command(int m);
/*后置条件:编辑器运行结束,并返回文本。 */
string done_command();
/*后置条件:退出编辑器*/
string quit_command();
/*后置条件:将在内存的文本文件存盘*/
string save_command();
/*后置条件:打开一个新文件*/
string open_command();
/*后置条件:输出命令的帮助信息*/
string help_command();
/*后置条件:将文本中第k行至第m行输出至标准输出*/
string print_command(int k, int m);
/*后置条件:将文本中的所有字符串str1的出现替换成字符串str2*/
string replace_command();
list<string> text; //the text in the file
list<string>::iterator current; //represent the current line
int currentLineNumber; //the index number of the current line
bool inserting; //true when the file is in insertion mood
}; // Editor
//Constructor of class Editor
//initially no text in it
Editor::Editor()
{
text.clear();
current = text.begin();
currentLineNumber = -1;
inserting = false;
}
//parse function for class Editor
//determines the type of instructions or texts
//return an error if there is any
string Editor::parse(const string &line)
{
if(line.substr(0,7) == "$Insert" && inserting == false)
{
//Insert line instruction
inserting = true;
return " ";
}
else if(line.substr(0,7) == "$Delete" )
{
//Delete line instruction
inserting = false;
int k = 0, m = 0, j;
if(line[8] == '-')
//the first line number is negative
return "***Error:The first line number < 0.";
else if(line[8] < '0' || line[8] > '9')
//the command is not followed by integers
return "***Error:The command is not followed by two integers.";
else
{
//command is followed by two positive integers
//calculate k
for(j = 8 ; line[j] >= '0' && line[j] <= '9' && line[j] != ' ';j++)
{
k = k * 10;
k += (line[j] - '0');
}
//skip the space between two integers
j++;
//calculate m
for(; line[j] >= '0' && line[j] <= '9';j++)
{
m = m * 10;
m += (line[j] - '0');
}
if(k > m)
return "***Error:The first line number > the second.";
else if(k < 0)
return "***Error:The first line number < 0.";
else if(m >= text.size())
return "***Error:The second line number > the last line number.";
else
return delete_command(k, m);
}
}
else if(line.substr(0,5) == "$Line" )
{
//change current line instruction
int m;
inserting = false;
if(line.substr(5,2) == "-1")
{
//change the current line number to 0 to insert to line 0
m = -1;
return line_command(m);
}
else
{
//change the current line number into m
m = 0;
for(int j = 6;(line[j] >= '0' && line[j] <= '9');j++)
{
m = 10 * m;
m += (line[j] - '0');
}
return line_command(m);
}
}
else if(line.substr(0,6) == "$Print")
{
//Print lines instruction
inserting = false;
int k = 0, m = 0, j;
if(line[7] == '-')
//the first line number is negative
return "***Error:The first line number < 0.";
else if(line[7] < '0' || line[7] > '9')
//the command is not followed by integers
return "***Error:The command is not followed by two integers.";
else
{
//command is followed by two positive integers
//calculate k
for(j = 7 ; line[j] >= '0' && line[j] <= '9' && line[j] != ' ';j++)
{
k = k * 10;
k += (line[j] - '0');
}
//skip the space between two integers
j++;
//calculate m
for(; line[j] >= '0' && line[j] <= '9';j++)
{
m = m * 10;
m += (line[j] - '0');
}
if(k > m)
return "***Error:The first line number > the second.";
else if(k < 0)
return "***Error:The first line number < 0.";
else if(m >= text.size())
return "***Error:The second line number > the last line number.";
else
return print_command(k, m);
}
}
else if(line.substr(0,5) == "$Done" )
{
//edition done and print all the text
inserting = false;
return done_command();
}
else if(line.substr(0,5) == "$Quit")
{
//Quit the editor instruction
inserting = false;
return quit_command();
}
else if(line.substr(0,5) == "$Save")
{
//Save the data into a file
inserting = false;
return save_command();
}
else if(line.substr(0,5) == "$Open")
{
//Open a file and import its data
inserting = false;
return open_command();
}
else if(line.substr(0,8) == "$Replace")
{
//Replace strings instruction
inserting = false;
return replace_command();
}
else if(line.substr(0,5) == "$Help")
{
//show Help information instruction
inserting = false;
return help_command();
}
else if(inserting == true)
//insert lines
return insert_command(line);
else
{
//error occurs
return "***Error:This is an illegal instruction.Please enter again.";
}
}
//Insert line instruction
//insert a line to the current position
string Editor::insert_command(const string& line)
{
if(currentLineNumber == -1)
{
//no text available in the file then create a new line
text.push_front(line);
currentLineNumber++;
current = text.begin();
current++;
}
else
{
//insert the new line to the current position
text.insert(current,line);
currentLineNumber++;
}
return " ";
}
//Delete lines instruction
//delete lines from line k to line m
string Editor::delete_command(int k, int m)
{
list<string>::iterator temp = text.begin();
if(k == 0)
{
list<string>::iterator itr = temp;//itr and temp both point to line 0
for(int i = k; i <= m;i++)
itr = text.erase(itr);
if(currentLineNumber - 1 <= m && currentLineNumber - 1 >= k)
{
current = text.begin();
currentLineNumber = -1;
}
}
else
{
for(int i = 0;i < k - 1 ;i++)
temp++;
list<string>::iterator itr = temp;//itr and temp both point to line k - 1
itr++;//itr points to line k
for(int i = k; i <= m;i++)
itr = text.erase(itr);
if(currentLineNumber - 1 <= m && currentLineNumber - 1 >= k)
{
current = temp;
currentLineNumber = k - 1;
}
}
return " ";
}
//change current line instruction
//the next line to be inserted will be in the indicated line
string Editor::line_command(int m)
{
if(m >= text.size() && m >= 0)
//the line number is greater than the last line number
return "***Error:the line number is greater than the last line number.";
else if(m == -1)
{
//current line should be set to the first line
current = text.begin();
currentLineNumber = -1;
return " ";
}
else
{
//current line should be set to line m
currentLineNumber = m;
list<string>::iterator temp = text.begin();
for(int i = 0;i <= m ;i++)
temp++;
current = temp;//current points to line m + 1
return " ";
}
}
//Print instruction
//print the text from line k to line m
string Editor::print_command(int k, int m)
{
list<string>::iterator temp = text.begin();//temp points to line 0
for(int i = 0;i < k -1 ;i++)//increment temp for k - 1 times
temp++;
list<string>::iterator itr = temp;//itr points to line k
list<string>::iterator preCurrent = current;
preCurrent--;//preCurrent points to currents' previous line
for(int i = k; i <= m; i++)
{
if(itr == preCurrent)
cout << '>';
else
cout << ' ';
cout << i << " " << *itr << endl;
itr++;
}
return " ";
}
//Done instruction
//edition down and print all the text
string Editor::done_command()
{
if(text.empty())
{
//there is no line in the text
cout << "The text is empty." << endl ;
return " ";
}
else
{
//print all the lines in the text
cout << "Here is the final text:" << endl << endl;
list<string>::iterator itr = text.begin();
while(itr != text.end())
{
list<string>::iterator preCurrent = current;
preCurrent--;
if(current == text.begin() && itr == current) // mark the current line
cout << '>';
else if(itr == preCurrent)
cout << '>';
else
cout << ' ';
cout << *itr << endl;
itr++;
}
return " ";
}
}
string Editor::quit_command()
{
return "Please press the Enter key to close this output window.";
}
string Editor::save_command()
{
cout << "Please enter the name of the document:" << endl;
ofstream output;
string fileName;
cin >> fileName; // cin the file's name
output.open(fileName.c_str()); // open the file
list<string>::iterator itr = text.begin();
while(itr != text.end()) // put all lines of the data into the file
{
output << *itr << endl;
itr++;
}
output.close();
return "File saved.";
}
string Editor::open_command()
{
cout << "Please enter the name of the document:" << endl;
fstream input;
string fileName;
cin >> fileName; // cin the file's name
input.open(fileName.c_str()); // open the file
string temp; // use temp as a contain of the data in the file
while(getline(input, temp))
{
if(currentLineNumber == -1)
{
//no text available in the file then create a new line
text.push_front(temp);
currentLineNumber++;
current = text.begin();
current++;
}
else
{
//insert the new line to the current position
text.insert(current,temp);
currentLineNumber++;
}
}
input.close();
return "File opened.";
}
string Editor::help_command()
{
cout << "$Insert: 插入命令,将此命令之后的文本行插入到当前行后,直到遇到下一个编辑命令。插入的最后一行成为当前行。如果原文本空,则插入从第一行开始。" << endl;
cout << "$Delete: 删除第k至第m行。如果当前行包括在删除范围,则第k-1行成为当前行(如果k=0,则第0行成为当前行);否则,当前行不变。" << endl;
cout << "$Line m : 改变当前行命令,第m行成为当前行。" << endl;
cout << "$Print k m :打印命令,将文本中第k行至第m行输出至标准输出。" << endl;
cout << "$Done :完成编辑,打印文本。" << endl;
cout << "$Quit :退出程序。" << endl;
cout << "$Save :将在内存的文本文件存盘。" << endl;
cout << "$Replace str1 str2 :将文本中的所有字符串srt1 的出现替换成字符串str2。" << endl;
cout << "$Help :输出命令帮助信息。" << endl;
return " ";
}
string Editor::replace_command()
{
string str1, str2;
cout<< endl << "Enter the string 1: " << endl;
getline(cin,str1);
cout<< "Enter the string 2: " << endl;
getline(cin,str2);
list<string>::iterator itr = text.begin();
while(itr != text.end()) // traverse all the lines, if one line equals to str1, change it into str2
{
if(*itr == str1)
*itr = str2;
itr++;
}
cout << endl << "Replace completed" << endl;
return " ";
}
#include <iostream>
using namespace std;
int main()
{
const string PROMPT = "Please enter a line: ";
const string COMMAND_START = "$";
const string QUIT_COMMAND = "$Quit";
const string CLOSE_WINDOW_PROMPT = "Please press the Enter key to close this output window.";
Editor editor;
string result;
string line;
do
{
cout << PROMPT << endl;
getline(cin,line);
result = editor.parse(line);
if(result.substr(0, 1) == COMMAND_START)
cout << result.substr(1) << endl;
else
cout << result << endl;
} while(line != QUIT_COMMAND); // if line equals to QUIT_COMMAND, then end the loop to quit
cin.get();
return 0;
}
test2
最新推荐文章于 2019-10-02 21:07:00 发布