1. 程式人生 > >用C++實現簡易文字編輯器

用C++實現簡易文字編輯器

1.簡易文字編輯器

2.用連結串列實現,儲存到檔案中

#include<iostream>
#include<string>
#include<cstdlib>
#include<ctype.h>
#include<cstdio>
#include<fstream>
using namespace std;
int NumberCount=0;//數字個數
int CharCount=0;//字母個數
int PunctuationCount=0;//標點符號個數
int BlankCount=0;//空白符個數

class Node
{
public:
    string character;
    int cursor;
    int offset;
    Node* next;
    Node(){
        cursor=0;//每行的游標初始位置
        offset=0;//每行的初始偏移位置
        next=NULL;
    }
};

class TextEditor
{
private:
    Node* head;
    string name;
    int line;//可更改的行數
    int length;//行數
public:
    TextEditor();
    ~TextEditor();
    string GetName();
    void SetName(string name);
    int GetCursor();
    int MoveCursor(int offset);
    int SetCursor(int line,int offset);
    void AddText(const string s);
    void InsertText(int seat,string s);
    int FindText(string s);
    void DeleteText(string s);
    int GetLine();
    void Count();
    friend ostream& operator<<(ostream& out,TextEditor &text);
    Node* Gethead(){
        return head;
    }
    //int GetLength()
    //{
   //     return length;
   // }
  //  int FindText(string s);
  //  void DeleteText(int seat,string s);
};

TextEditor::TextEditor()
{
    head=NULL;
    name="test";//檔案初始名
    //tail=NULL;
    line=1;
    length=0;
}

TextEditor::~TextEditor()
{
    Node* p=head;
    Node* q;
    while(p!=NULL){
        q=p->next;
        delete p;
        p=q;
    }

}

int TextEditor::GetLine()
{
    return line;
}

string TextEditor::GetName()
{
    return name;
}

void TextEditor::SetName(string name)
{
    this->name=name;
}

int TextEditor::GetCursor()
{
    Node *p=head;
    while(p->next!=NULL)
        p=p->next;
    return p->cursor;
}

int TextEditor::MoveCursor(int offset)
{
    Node *p=head;
    int i=1;
    if(length+1<line){
        cout<<"輸入錯誤!"<<endl;
        exit(0);
    }
    else{
        while(p->next!=NULL&&i<line){
            p=p->next;
            i++;
        }
    }
    if(offset>p->character.length()){
        cout<<"移動位置太大!"<<endl;
        exit(0);
    }
    else
       p->cursor+=offset;
    //cout<<"p  ->cursor="<<p->cursor<<endl;
    return p->cursor;
}

int TextEditor::SetCursor(int line,int offset)
{
    this->line=line;
   //cout<<"line="<<this->line<<endl;
    return MoveCursor(offset);
}

void TextEditor::AddText(const string s)
{
    line=length+1;
    Node* p=new Node;
    Node* q=head;
    p->character=s;
    p->next=NULL;
    if(head==NULL)
        head=p;
    else{
        while(q->next!=NULL)
            q=q->next;
        q->next=p;
    }

        length++;
       // line++;
}

void TextEditor::InsertText(int seat,string s)
{
    Node *p=head;
    int i=1;
    if(length+1<line){
        cout<<"輸入錯誤!"<<endl;
        exit(0);
    }
    else{
        while(p->next!=NULL&&i<line){
            p=p->next;
            i++;
        }
    }
    //MoveCursor(seat);
    //cout<<"p->cursor="<<p->cursor<<endl;
    string substr;
    for(int i=seat;i<s.length()+seat&&i<=p->character.length();i++)
    substr+=p->character[i];

    p->character.insert(p->cursor,s);


    cout<<"substr="<<substr<<endl;
    DeleteText(substr);//覆蓋子串
    p->cursor=0;//游標清零
}

ostream& operator<<(ostream& out,TextEditor &text)
{
    int i=1;
    Node* p=text.Gethead();
    while(p!=NULL){
        out<<p->character<<endl;
        p=p->next;
    }
   // cout<<"length="<<text.GetLength()<<endl;
    return out;
}

int TextEditor::FindText(string P)
{
    Node* q=head;
    //int templine=1;
    line=1;
    int p=0;
    int t=0;
    int plen=P.length()-1;
    //cout<<"P="<<P<<endl;
    //cout<<"plen="<<plen<<endl;
    int tlen=q->character.length();
    while(q!=NULL){
            p=0;
            t=0;
        tlen=q->character.length();
        if(tlen<plen){
            line++;
             q=q->next;
        }

        while(p<plen&&t<tlen){
            if(q->character[t]==P[p]){
                t++;
                p++;
            }
            else{
                t=t-p+1;
                p=0;
            }
        }
      //  cout<<"P="<<P<<endl;
      //  cout<<"p="<<p<<endl;
      //  cout<<"plen="<<plen<<endl;
        if(p>=plen){

            return t-plen+1;
        }


        else{
            line++;
            q=q->next;
        }

    }
    return -1;
}

void TextEditor::DeleteText(string s)
{
    Node *p=head;
    int i=1;
    int k=FindText(s);
    if(k==-1)
        cout<<"未出現該字串!"<<endl;
    else{
        while(p!=NULL&&i<line){
            p=p->next;
           // cout<<p->character<<endl;
            i++;
        }

        p->character.erase(k-1,s.length());
        cout<<"刪除成功!"<<endl;
    }
}

void TextEditor::Count()
{
    Node *p=head;
    NumberCount=0;
    CharCount=0;
    PunctuationCount=0;
    BlankCount=0;
    while(p!=NULL){
            for(int i=0;i<p->character.length();i++){
                if(p->character[i]>='0'&&p->character[i]<='9')
                    NumberCount++;
                else if(p->character[i]>'a'&&p->character[i]<'z'||p->character[i]>'A'&&p->character[i]<'Z')
                    CharCount++;
                else if(ispunct(p->character[i]))
                    PunctuationCount++;
                else if(p->character[i]==' ')
                    BlankCount++;
            }
            p=p->next;
    }
}

int main()
{
    int i,j,k,n=2;
    string s,t,name;
    TextEditor text;
    cout<<"---------------------------------------"<<endl;
    cout<<"1.新增字元"<<endl;
    cout<<"2.設定文件名字"<<endl;
    cout<<"3.獲取文件名字"<<endl;
    cout<<"4.顯示游標位置"<<endl;
    cout<<"5.設定游標位置,在游標位置處插入文字"<<endl;
    cout<<"6.在文件中查詢文字"<<endl;
    cout<<"7.在文件中刪除文字"<<endl;
    cout<<"8.統計字母、數字、標點符號、空白符號及總字元個數"<<endl;
    cout<<"9.輸入文字"<<endl;
    cout<<"0.退出"<<endl;
    while(n){
       // cout<<endl;
        cout<<endl;
        cout<<"---------------------------------------"<<endl;
        cout<<"請輸入:";
        cin>>n;
        getchar();
        switch(n){
            case 1: cout<<"請輸入字元:"; getline(cin,s,'\n'); text.AddText(s); break;
            case 2: cout<<"請輸入文件名字:"; cin>>name; text.SetName(name); break;
            case 3: cout<<text.GetName()<<endl; break;
            case 4: cout<<"游標在第"<<text.GetLine()<<"行,第"<<text.GetCursor()<<"個字元前!"<<endl; break;
            case 5:{
                cout<<"輸入行數:";
                cin>>i;
                cout<<"游標在第"<<text.GetCursor()<<"個字元前!"<<endl;
                cout<<"輸入移動位數:";
                cin>>j;
                cout<<"輸入插入字元:";
                getchar();
                getline(cin,s);
                text.InsertText(text.SetCursor(i,j),s); break;
            }
            case 6: {
                cout<<"輸入查詢的字串:";
                getline(cin,s);
                int k=text.FindText(s);
                if(k==-1)
                    cout<<"查詢失敗!"<<endl;
                else
                    cout<<"所查詢文字首次出現在:"<<text.GetLine()<<"行,第"<<k<<"個字元處!"<<endl;
                    break;
            }
            case 7: cout<<"輸入要刪除的字串:"; getline(cin,s); text.DeleteText(s); break;
            case 8: {
                text.Count();
                cout<<"文件中共有:"<<endl;
                cout<<NumberCount<<"個數字"<<endl;
                cout<<CharCount<<"個字母"<<endl;
                cout<<PunctuationCount<<"個標點符號"<<endl;
                cout<<BlankCount<<"個空白字元"<<endl;
                cout<<"共有"<<NumberCount+CharCount+PunctuationCount+BlankCount<<"個字元!"<<endl;
                break;
            }
            case 9: cout<<text; break;
            case 0:{
                string ss=text.GetName();
                ss+=".txt";
                cout<<ss<<endl;
                ofstream outFile(ss.c_str());
                Node* p=text.Gethead();
                while(p!=NULL){
                    outFile<<p->character<<endl;
                    p=p->next;
                }
                exit(0);
                break;
            }
            default: cout<<"輸入錯誤,請重新輸入!"<<endl; break;
        }

    }
}