一个行编辑器的实现

放假无聊,而且又不想学什么java,web编程等等。觉得自己oop思想还是不够,所以就打算把乔老的《数据结构与算法实验教程》的实验全部做完再说。下面就做了一个行编辑器:

Editor_H.h:

#ifndef Editor_H
#define Editor_H

#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 command_check(const string& line);
 
 /*如果line不是很长,则将其插入编辑器,并返回一个空行;否则,返回错误信息。
 */
 string insert_command(const string& line);
 
 /*后置条件:如有可能,删除第k至第m行,并返回一个空行;否则,返回错误信息。
 */
 string delete_command(const string& line);
 
 /*后置条件:如有可能,第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(const string& line);

 /*后置条件:将文本中的所有字符串str1的出现替换成字符串str2
 */
 string replace_command();
 list<string> text;    //文本
 list<string>::iterator current;    //指向当前行的指针
 int currentLineNumber;            //记录当前行的编号
 bool inserting;           //判断是否进入了insert操作
};

#endif

 

Editor.cpp:

#include "Editor_H.h"


Editor::Editor()
{
 text.clear();
 current = text.begin();
 currentLineNumber = -1;
 inserting = false;
}

string Editor::parse(const string &line)
{
 if(line.substr(0,7) == "$Insert" && inserting == false)
 {
  inserting = true;
  return " ";
 }
 else if(line.substr(0,7) == "$Delete" )
 {
  inserting = false;
  return delete_command(line);
 }
 else if(line.substr(0,6) == "$Print")
 {
  inserting = false;
  return print_command(line);
 }
 else if(line.substr(0,5) == "$Line" )
 {
  int a;
  inserting = false;
  if(line.substr(5,2) == "-1")
  {
   a = -1;
   return line_command(a);
  }
  else
  {
   int i = 0,j,a = 0;
   for(j = 6;(line[j] >= '0' && line[j] <= '9');j++)
   {
    a = 10 * a;
    a += (line[j] - '0');
   }
   return line_command(a);
  }
 }
 else if(line.substr(0,5) == "$Done" )
 {
  inserting = false;
  return done_command();
 }
 else if(line.substr(0,5) == "$Quit")
 {
  inserting = false;
  return quit_command();
 }
 else if(line.substr(0,5) == "$Save")
 {
  inserting = false;
  return save_command();
 }
 else if(line.substr(0,5) == "$Open")
 {
  inserting = false;
  return open_command();
 }
 else if(line.substr(0,5) == "$Help")
 {
  inserting = false;
  return help_command();
 }
 else if(line.substr(0,8) == "$Replace")
 {
  inserting = false;
  return replace_command();
 }
 else if(inserting == true)
  return insert_command(line);
 else
 {
  return "***Error:This is an illegal instruction.Please enter again.";
 }
}

string Editor::insert_command(const string& line)
{
 if(currentLineNumber == -1)
 {
  text.push_front(line);
  currentLineNumber++;
  current = text.begin();
  current++;
 }
 //在当前行的下一位置插入
 else
 {
  text.insert(current,line);
  currentLineNumber++;
 }
 return " ";   //返回一个空行,表示插入成功
}

string Editor::delete_command(const string &line)
{
 int k = 0,m = 0,i = 0,j;
 //捕获第一个参数
 if(!((line[8] >= '0' && line[8] <= '9') || (line[8] == '-')))
  return "***Error:The command is not followed by two integers.";
 else if(line[8] == '-')
  return "***Error:The first line number < 0.";
 else
 {
  for(j = 8 ; (line[j] >= '0' && line[j] <= '9');j++)
  {
   k = k * 10;
   k += (line[j] - '0');
  }
  while(line[j] == ' ')
   j++;
  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
  {
   list<string>::iterator temp = text.begin();
   for(i = 0;i < k -1 ;i++)
    temp++;
   list<string>::iterator itr = temp;
   for(i = k; i <= m;i++)
   {
    itr = text.erase(itr);
   }
   current = temp;
   currentLineNumber = k -1;
   return " ";     //删除成功,返回一个空行
  }
 }
}

string Editor::print_command(const string& line)
{
 int k = 0,m = 0,i = 0,j;
 //捕获第一个参数
 if(!((line[7] >= '0' && line[7] <= '9') || (line[7] == '-')))
  return "***Error:The command is not followed by two integers.";
 else if(line[7] == '-')
  return "***Error:The first line number < 0.";
 else
 {
  for(j = 7 ; (line[j] >= '0' && line[j] <= '9');j++)
  {
   k = k * 10;
   k += (line[j] - '0');
  }
  while(line[j] == ' ')
   j++;
  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
  {
   list<string>::iterator temp = text.begin();
   for(i = 0;i < k -1 ;i++)
    temp++;
   list<string>::iterator itr = temp;
   for(i = k; i <= m;i++)
   {
    cout << i << " "  << *itr << endl;
    itr++;
   }
   return " ";     //删除成功,返回一个空行
  }
 }
}

string Editor::line_command(int m)
{
 int i;
 if(m >= text.size() && m >= 0)
  return "***Error:the line number is greater than the last line number.";
 else if(m == -1)
 {
  current = text.begin();
  currentLineNumber = -1;
  return " ";     //操作成功,返回一个空行。
 }
 else
 {
  currentLineNumber = m;
  list<string>::iterator temp = text.begin();
  for(i = 0;i < m ;i++)
   temp++;
  current = temp;
  current++;
  return " ";     //操作成功,返回一个空行。
 }
}

string Editor::done_command()
{
 if(text.empty())
 {
  cout << "The text is empty." << endl ;
  return " ";   //表示文本为空
 }
 else
 {
  cout << "Here is the final text:" << endl << endl;
  list<string>::iterator itr = text.begin();
  while(itr != text.end())
  {
   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 name;
 vector<string> file;
 list<string>::iterator qq = text.begin();
 cin >> name;
 file.push_back(name);
 vector<string>::const_iterator temp = file.begin();
 output.open(temp->c_str());
 while(qq != text.end())
 {
  output << *qq << endl;
  qq++;
 }
 output.close();
 return "***Finish.";
}

string Editor::open_command()
{
 text.clear();
 current = text.begin();
 currentLineNumber = -1;
 return "***Finish.";
}


string Editor::help_command()
{
 cout << "*** $Insert     -- 插入命令          ***" << endl;
 cout << "*** $Delete k m -- 删除第k~第m行     ***" << endl;
 cout << "*** $Line m     -- 使第m行变成当前行 ***" << endl;
 cout << "*** $Print k m  -- 输出第k~第m行     ***" << endl;
 cout << "*** $Done       -- 完成编辑,打印文本 ***" << endl;
 cout << "*** $Quit       -- 退出编辑器        ***" << endl;
 cout << "*** $Save       -- 在内存文本文件存盘***" << endl;
 cout << "*** $Open       -- 打开一个新文件    ***" << endl;
 cout << "*** $Replace    -- 替换命令          ***" << endl;
 cout << "*** $Help       -- 输出命令帮助信息  ***" << endl;
 return "";
}

string Editor::replace_command()
{
 string str1,str2;
 cout<< "***Please enter the string1:" << endl;
 getline(cin,str1);
 cout<< "***Please enter the string2:" << endl;
 getline(cin,str2);
 list<string>::iterator itr = text.begin();
 while(itr!=text.end())
 {
  if(*itr == str1)
   *itr = str2;
  itr++;
 }
 return "";    //操作完成,返回空行
}

 text.cpp:

#include <iostream>
#include "Editor_H.h"
using namespace std;

int main()
{
 const string PROMPT = "Please enter a line: ";
 const string COMMAND_START = "$";
 const string DONE_COMMAND = "$Done";
 const string CLOSE_WINDOW_PROMPT = "Please press the Enter key to close this output window.";

 Editor editor;
 string result;
 string line;
 int i = 100;
 do
 {
  cout << PROMPT << endl;
  getline(cin,line);
  if(line == "")
   result = "***Save is finished.";
  else
   result = editor.parse(line);
  cout << result << endl;
  list<string>::iterator ss = editor.text.begin();
 }while(result != CLOSE_WINDOW_PROMPT);    //使行编辑器退出

 return 0;
}

 

效果自己看吧:

 

posted @ 2013-01-29 13:48  中大黑熊  阅读(392)  评论(0编辑  收藏  举报