?? editor.h
字號:
// 文本編輯類
class Editor
{
public:
// 方法聲明:
Editor(ifstream *file_in, ofstream *file_out); // 構造函數
bool get_command(); // 讀取操作命令字符user_command
void run_command(); // 運行操作命令
private:
// 成員變量
DList<String> text; // 文本緩存
int current_line_no; // 當前行號
ifstream *infile; // 輸入文件
ofstream *outfile; // 輸出文件
char user_command; // 用戶命令
// 輔助函數
bool next_line(); // 轉到下一行
bool previous_line(); // 轉到前一行
bool goto_line(); // 轉到指定行
bool insert_line(); // 插入一行
bool substitute_line(); // 替換指定行
bool change_line(); // 改變當前行
void read_file(); // 讀入文本文件
void write_file(); // 寫文本文件
void find_string(); // 查找串
bool user_says_yes(); // 回答yes/no
bool delete_line(); //刪除當前行
};
Editor::Editor(ifstream *file_in, ofstream *file_out)
// 構造函數,用輸入文件file_in和輸出文件file_out
// 構造編輯器
{
infile = file_in; // 輸入文件
outfile = file_out; // 輸出文件
current_line_no = 0; // 當前行號
}
bool Editor::get_command()
// 讀取操作命令字符user_command,除非user_command
//為'q',否則返回true
{
cout<<endl;
String cur_line;
if (current_line_no != 0)
{
text.setPos(current_line_no - 1);
text.getValue(cur_line);
cout << current_line_no << " : "
<< cur_line.c_str() << endl <<"?";
}
else
{
cout << "文件緩存是空的(請用輸入r讀取文件到緩存中). \n?";
}
cin >> user_command; // 忽略空格并取得操作命令字符
user_command = tolower(user_command);// 轉換為小字字母
while (cin.get() != '\n'); // 忽略用戶輸入的其他字符
if (user_command == 'q')
{ // user_command為'q'時返回false
return false;
}
else
{ // user_command不為'q'時返回true
return true;
}
}
void Editor::run_command()
// 運行操作命令
{
String temp_string; // 臨時串
switch (user_command)
{
case 'b': // 轉到第1行b(egin)
if (text.leftLength() + text.rightLength() == 0)
{ // 文本緩存空
cout << " 警告: 文本緩存空 " << endl;
}
else
{ // 文本緩存非空, 轉到第1行
current_line_no = 1;
}
break;
case 'c': // 替換當前行c(hange)
if (text.leftLength() + text.rightLength() == 0)
{
cout << " 警告: 文本緩存空" << endl;
}
else if (!change_line())
{ // 替換當失敗
cout << " 錯誤: 替換失敗 " << endl;
}
break;
case 'd': // 刪除當前行d(el)
if (!delete_line())
{ // 刪除當前行失敗
cout << " 錯誤: 刪除失敗 " << endl;
}
break;
case 'e': // 轉到最后一行e(nd)
if (text.leftLength() + text.rightLength() == 0)
{
cout << " 警告: 文本緩存空 " << endl;
}
else
{ // 轉到第一行
current_line_no = text.leftLength() + text.rightLength();
}
break;
case 'f': // 從當前行開始查找指定文本f(ind)
if (text.leftLength() + text.rightLength() == 0)
{
cout << " 警告: 文本緩存空 " << endl;
}
else
{ // 從當前行開始查找指定文本
find_string();
}
break;
case 'g': // 轉到指定行g(o)
if (!goto_line())
{ // 轉到指定行失敗
cout << " 警告: 沒有那樣的行" << endl;
}
break;
case '?': // 獲得幫助?
case 'h': // 獲得幫助h(elp)
cout<<"\t\t\t\t\t有效命令"<<endl;
cout<<"\t\t----------------------------------------------------"<<endl;
cout << "\t\t* \t b(egin) | c(hange) | d(el) | e(nd)\t *" << endl
<< "\t\t* \t f(ind) | g(o) | h(elp) | i(nsert)\t *"<<endl
<< "\t\t* \t l(ength) | n(ext) | p(rior) |q(uit)\t *" << endl
<< "\t\t* \t r(ead) | s(ubstitute) | v(iew) | w(rite) *" << endl;
cout<<"\t\t----------------------------------------------------"<<endl;
break;
case 'i': // 插入指定行i(nsert)
if (!insert_line())
cout << " 錯語: 插入行出錯 " << endl;
break;
case 'l': // 顯示文本行數l(ength)
cout << "在文件中有 "
<< text.leftLength() + text.rightLength()
<< " 行文本串." << endl;
if (text.leftLength() + text.rightLength() > 0)
{ // 非空文件
String cur_line; // 當前行
text.setPos(current_line_no - 1);
text.getValue(cur_line);
cout << "當前行有:"
<< strlen(cur_line.c_str()) <<" 個字符"<< endl;
}
break;
case 'n': // 轉到下一行n(ext)
if (!next_line())
{ // 無下一行
cout << " 警告: 當前行已是最后一行" << endl;
}
break;
case 'p': // 轉到前一行p(rior)
if (!previous_line())
{ // 無前一行
cout << " 警告: 當前行已是第一行" << endl;
}
break;
case 'r': // 讀入文本件r(ead)
read_file();
break;
case 's': // 替換指定行s(ubstitute)
if (!substitute_line())
{ // 替換指定行失敗
cout << " 錯誤: 替換指定行失敗 " << endl;
}
break;
case 'v': // 顯示文本v(iew)
for (text.setStart(); text.getValue(temp_string); text.next())
{ // 顯示各行
cout << temp_string.c_str() << endl;
}
break;
case 'w': // 寫文本緩存到輸出文件中w(rite)
if (text.leftLength() + text.rightLength() == 0)
{ // 文本緩存空
cout << " 警告: 文本緩存空" << endl;
}
else
{ // 寫文本緩存到輸出文件中
write_file();
cout<<"寫入成功"<<endl;
}
break;
default :
cout << "輸入h或?獲得幫助或輸入有效命令字符: \n";
}
}
void Editor::read_file()
// 讀入文本件
{
bool proceed = true;
if (text.leftLength() + text.rightLength() > 0)
{ // 文本緩存非空
cout << "文本緩存非空; 讀入文件時將復蓋它." << endl;
cout << " 回答yes將執行此操作? " << endl;
if (proceed = user_says_yes())
{ // 回答yes
text.clear();
}
}
char terminal_char;
int file_size=0;
while (proceed)
{
//××××××××××××××××××××××××××××××
String in_string = read_in(*infile, terminal_char);
file_size+=in_string.getSize();
//判斷輸入文件是否為空
if(file_size==0)
{
cout<<"輸入文件為空,如果你想從鍵盤輸入文本到緩存請回答(Y),否則回答(N):";
if(user_says_yes())
{
insert_line();
}
}
if (terminal_char == EOF)
{ // 以文件結束符結束, 輸入已結束
proceed = false;
if (strlen(in_string.c_str()) > 0)
{ // 插入非空串
text.append(in_string);
}
}
else
{ // 輸入未結束
text.append(in_string);
}
}
if (text.leftLength() + text.rightLength() == 0)
{ // 當前文本緩存為空
current_line_no = 0;
}
else
{ // 當前文本緩存非空
current_line_no = 1;
}
infile->clear();
(*infile).seekg(0);
}
void Editor::write_file()
// 寫文本緩存到輸出文件中
{
String cur_line;
for (text.setStart(); text.getValue(cur_line); text.next())
{ // 寫文本緩存各行到輸出文件中
*outfile<<cur_line.c_str()<<endl;
}
}
bool Editor::user_says_yes()
// 回答yes/no
{
char answer;
cin >> answer;
answer = tolower(answer); // 轉換為小寫字母
if (answer == 'y' || answer == 't' || answer=='o')
{ // 回答yes
return true;
}
else
{ // 回答no
return false;
}
}
bool Editor::insert_line()
// 插入指定行
{
int line_number;
cout << " 輸入指定行號: ";
cin >> line_number;
while (cin.get() != '\n'); // 跳過其他字符
cout << " 輸入新行文本串: ";
String to_insert = read_in(cin);
text.setPos(line_number - 1);
if (text.insert(to_insert))
{ // 插入成功
current_line_no = line_number;
return true;
}
else
{ // 插入失敗
return false;
}
}
void Editor::find_string()
// 從當前行開始查找指定文本
{
int index;
cout << "輸入被查找的文本串:" << endl;
String search_string = read_in(cin);
String cur_line; // 當前行
text.setPos(current_line_no - 1);
text.getValue(cur_line);
while ((index = strstr(cur_line, search_string)) == -1)
{
if (current_line_no < text.leftLength() + text.rightLength())
{ // 查找下一行
current_line_no++;
text.setPos(current_line_no - 1);
text.getValue(cur_line);
}
else
{ // 已查找完所有行
break;
}
}
if (index == -1)
{ // 查找失敗
cout << "查找串失敗.";
}
else
{ // 查找成功
cout << cur_line.c_str() << endl;
for (int i = 0; i < index; i++)
{ // 在查找串前的位置顯行空格
cout << " ";
}
for (int j = 0; j < strlen(search_string.c_str()); j++)
{ // 在查找串前的位置顯行^
cout << "^";
}
}
cout << endl;
}
bool Editor::change_line()
// 替換當前行,用戶輸入當前行中的指定文本,用輸入的新文本替換指定文本
// 替換成功返回true,否則返回false
{
bool result = true;
cout << " 輸入要被替換的指定文本: ";
String old_text = read_in(cin);
cout << " 輸入新文本:";
String new_text = read_in(cin);
String cur_line; // 當前行
text.setPos(current_line_no - 1);
text.getValue(cur_line);
int index = strstr(cur_line, old_text);
if (index == -1)
{ // 模式匹配失敗
result = false;
}
else
{ // 模式匹配成功
String new_line; // 新行
strncpy(new_line, cur_line, index); // 復指定文本前的串
strcat(new_line, new_text); // 連接新文本串
const char *old_line = (cur_line).c_str();
strcat(new_line, (String)(old_line + index +strlen(old_text.c_str())));// 連接指定文本后的串
String strTem;
// 設置當前行新串
text.remove(strTem); // 刪除舊行
text.insert(new_line); // 插入新行
}
return result;
}
bool Editor::substitute_line()
// 替換指定行
{
int line_number;
char ch;
String new_line;
cout << " 輸入指定行號:";
cin >> line_number;
if(line_number < 1 || line_number > text.leftLength() + text.rightLength())
{ // 范圍錯
return false;
}
else
{
current_line_no = line_number;
cout<<" 輸入新行文本串: ";
while ((ch = cin.get()) != '\n'); // 跳過行中其它字符
new_line = read_in(cin); // 輸入新行
text.setPos(line_number - 1);
String strTem;
// 替換第line_number行
text.remove(strTem); // 刪除舊行
text.insert(new_line); // 插入新行
return true;
}
}
bool Editor::next_line()
// 轉到下一行
{
if ( current_line_no >= text.leftLength() + text.rightLength())
{ // 當前行號已是最后一行
return false;
}
else
{ // 當前行號不是最后一行
current_line_no++;
return true;
}
}
bool Editor::previous_line()
{
//轉到前一行
if(current_line_no==1)
{// 當前行是第一行
return false;
}
else
{
current_line_no--;
return true;
}
current_line_no++;
}
bool Editor::goto_line()
{
int line_no;
cout<<"請指定要轉到的行號:";
cin >>line_no;
if( line_no<0||line_no>text.leftLength() + text.rightLength() )
{
return false;
}
else
{
text.setPos(line_no);
//將當前行號改為指定行行號以顯示指定行
current_line_no=line_no;
return true;
}
}
bool Editor::delete_line()
{
//如果只有一行文本
if(text.leftLength() + text.rightLength()==1)
{
text.clear();
current_line_no=0;
return true;
}
else
{
text.setPos(current_line_no - 1);
String strTem;
//如果當前行是最后行,則顯示上一行的內容
if(current_line_no ==text.leftLength() + text.rightLength())
current_line_no-=1;
return text.remove(strTem);
}
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -