文章标题


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


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值