In C++ Write a simple word processor that will accept text and commands as input
ID: 3862392 • Letter: I
Question
In C++ Write a simple word processor that will accept text and commands as input. The commands it should respond to are:
Substitute/oldstring/newstring
Substitute newstring for every occurrence of oldstring in the current line. Issue a message if oldstring does not appear in the current line. Print the changed line.
Type #
Print the contents of the next # lines, including the current one. Don’t print blank spaces at the end of a line. The current line should be the last typed.
Copy #
Copy the next # lines, including the current one, to a temporary storage area. The current line should not change.
Paste
Copy the contents of the temporary storage area to a position between the current line and the line following the current line. The current line should become the last line pasted.
Locate/string/
Find the next occurrence of the string and make the line containing it the current line. If string does not occur anywhere in the file after the current line, issue a message and don’t change the current line. Then print the current line.
Insert #
Insert # lines into the file following the current line. The current line should be the last line entered.
Delete #
Delete the next # lines, including the current one. Make the first line following the deleted section the current line.
Replace #
Replace the next # lines, beginning with the current one, with # lines. The current line should be the last line entered.
Move #
Locate & print the line # lines past the current line. Make that the current line.
Quit
Saves the file to disk and quits the editor
Attach A picture showing that the code compiled and running please
Explanation / Answer
#include <iostream>
#include <fstream>
#include <cmath>
#include <string>
using namespace std;
const bool DEBUG = false;
const int MAX = 100;
struct file // This contains the file information and contents
{
string contents[MAX];
string filNam;
int currLnInx;
int tot;
bool markupHighlighting;
};
int NumInpRdr(string); // Reads the numbers from user input
void Help(); // Prints out a help menu
void Markup(file&, int); // Does HTML highlighting
void MarkupApply(file&, string, int); // Applies the HTML highlighting to the file
//void Substitute(file&, string); // substitutes portions of lines of text
//void Type(file&, int); // prints text to the screen
//void Copy(file, string[], int&); // copies text
//void Paste(file&, string[], int, int); // pastes text
//void Locate(file &, string); // finds text
//void Insert(file &, int); // inputs text to the array
//void Delete(file &, int); // deletes text
//void Replace(file &, int); // replaces while lines of text text
//void Move(file &, int); // moves the current line
//void Quit(file); // quits the program, asks the users if they want to save.
void Open(file &); // allows the user to open a file
void New(file &); // allows the user to create a file
void Save(file); // saves the array to a file.
void IndexPrint(file); // for debugging, this prints the contents of the array.
int main() // Main program
{
file txtFile;
txtFile.currLnInx=-1;
txtFile.tot=0;
int inputValue=0, copyNumber;
string inputString, openYN, copyQue[MAX];
char inputChar, openYNtemp;
// ANIMATION LOOP GOES HERE
cout<<"~~~[1;32m Welcome [0m~~~ "; // first use of colors in the program
cout<<"Would you like to open an existing file? "
<< endl;
getline(cin, openYN);
if(openYN == "") // if the user simply presses enter, a new file is automatically created
{ // because if the user really did this, they were probably trolling.
cout<<"[1;31m-You'll have to be more specific next time.-[0m "<<endl;
New(txtFile);
}
else // Wow, the user entered valid input.
{
openYNtemp=openYN.at(0);
openYNtemp=toupper(openYNtemp);
switch(openYNtemp)
{
case 'Y':
Open(txtFile);
break;
default:
New(txtFile);
break;
}
}
inputChar=' '; // Initializes variable as a space just as an entry point.
while(inputChar!='Q') // Main event loop. //"if not quit"
{
switch(inputChar)
{
case ' ':
break;
case 'S':
Substitute(txtFile,inputString);
break;
case 'T':
Type(txtFile, inputValue);
break;
case 'C':
copyNumber=NumInpRdr(inputString); // Special variable for copy
// because it is used again with paste.
Copy(txtFile, copyQue, copyNumber);
break;
case 'P':
Paste(txtFile, copyQue, copyNumber, inputValue);
break;
case 'L':
Locate(txtFile, inputString);
break;
case 'I':
Insert(txtFile, inputValue);
break;
case 'D':
Delete(txtFile, inputValue);
break;
case 'R':
Replace(txtFile, inputValue);
break;
case 'M':
Move(txtFile, inputValue);
break;
case 'O':
Open(txtFile);
break;
case 'N':
New(txtFile);
break;
case '<': // Highlight
txtFile.markupHighlighting=true; // highlights the markup in the file '</>'
Markup(txtFile, inputValue);
break;
case '>': // Unhighlight
txtFile.markupHighlighting=false; // if false, it'll go through the motions
Markup(txtFile, inputValue); // again, but revert to the original array
break; // afterward.
case '*': // * saves file to disk
Save(txtFile);
break;
case '?':
Help(); // "I seem to be having difficulty with my lifestyle." -Arthur Dent
break;
case'.': // default for re-looping
break;
default:
cout<<"[1;31m'"<<inputString<<"'[0m"
<<" is not a valid command. "
<<endl
<<"Enter '?' for a list of valid commands. "
<<endl;
break;
}
if(DEBUG)
{
cout<<"[1;31m";
cout<<"--(DEBUG)--> tot: "<<txtFile.tot<<endl;
cout<<"--(DEBUG)--> currLnInx: "<<txtFile.currLnInx<<endl;
IndexPrint(txtFile);
cout<<"[0m";
}
cout<<"Command? "<<endl;
getline(cin, inputString);
if(inputString == "")
{
cout<<"[1;31m-You'll have to be more specific.-[0m "<<endl;
inputChar='.'; // resets the loop because the user was being unfriendly
}
else if(inputString.length()>=80) // If it takes up the entire default width of
{ // the window.
cout<<"[1;31m-That's a very long command, "
<<"I'm just but a humble Line Editor.-[0m "<<endl;
inputChar='.'; // resets the loop because the user was being unfriendly
}
else
{
inputChar=inputString.at(0);
inputChar=toupper(inputChar);
inputValue=NumInpRdr(inputString);
}
}
Quit(txtFile); // calls quit function, Y or N to save.
cout<<"Have a nice day!"<<endl;
return 0;
}
void Markup(file &txtFile, int colorIn) // Locates the markup and changes the color based on
{ // user input. Then calls MarkupApply.
int i, openFind, closeFind, len;
bool end = false;
string colorBegn, colorEnd = "[0m";
string toBeReplaced, replacement, finalString;
fabs(colorIn);
if(colorIn<=-1 or colorIn>=8)
{
colorIn=0; // Default color
cout<<"[1;31m-Invalid color. Color set to default.-[0m"<<endl;
}
switch(colorIn)
{
case 0:
colorBegn="[1;32m"; // colors two and zero are switched
break;
case 1:
colorBegn="[1;31m";
break;
case 2:
colorBegn="[1;30m"; // because if no colors are entered the
break; // default should be color two
case 3:
colorBegn="[1;33m";
break;
case 4:
colorBegn="[1;34m";
break;
case 5:
colorBegn="[1;35m";
break;
case 6:
colorBegn="[1;36m";
break;
case 7:
colorBegn="[1;37m";
break;
default:
cout<<"[1;31m-There seems to have been an error.-[0m"<<endl;
break;
}
i=0;
while(i<=txtFile.tot-1) // or reaches end, or none on the line
{
end = false;
openFind=0;
closeFind=0;
while(end != true)
{
openFind = txtFile.contents[i].find('<', closeFind);
closeFind = txtFile.contents[i].find('>', openFind)+1;
len=closeFind-openFind;
if(openFind >= 0 and closeFind >= 0)
{
toBeReplaced = txtFile.contents[i].substr(openFind, closeFind);
replacement=colorBegn+toBeReplaced+colorEnd;
//finalString="|"+toBeReplaced+"|"+replacement+"|";
//MarkupApply(txtFile, finalString, i);
txtFile.contents[i].replace(openFind, len, replacement);
}
end = true;
}
i++;
}
if(txtFile.markupHighlighting = false)
{
// UNHIGHLIGHTING GOES HERE
}
}
void Substitute(file &txtFile, string input_string) // substitutes '/string/' with '/other string/'
{
int pos, pos_2, pos_3, pos_old_string, txtfile_length, i;
int new_string_length, old_string_length, start_from;
bool check, exit;
char indicator;
// Substitute works with all characters, not just '/'
indicator = input_string.at(input_string.length()-1);
pos = input_string.find(indicator);////////////////////////
string temp_1, new_string, temp_2, old_string;
temp_1 = input_string.substr(pos + 1);
pos_2 = temp_1.find_last_of(indicator);////////////////////////////
old_string = temp_1.substr(0,pos_2);
temp_2 = temp_1.substr(pos_2+1);
new_string = temp_2.substr(0,temp_2.length()-1);
old_string_length = old_string.length();
new_string_length = new_string.length();
i = txtFile.currLnInx;
start_from = 0;
check = true;
exit = false;
string the_original_string = txtFile.contents[i];
if(txtFile.contents[i].find(old_string) == -1)//to show if no match string for the old_string.
{
cout<<"[1;31m-'"<<old_string<<"'[0m does not occur on line [1;31m"
<<i<<"[0m.- "<<endl;
}
if(txtFile.contents[i].empty() == true)//to leave if it empty.
{
cout<<"[1;31m-Line number "<<i+1<<" is empty.-[0m"<<endl;
check = false;
}
txtfile_length = txtFile.contents[i].length();
while(check and not exit)
{
txtfile_length = txtFile.contents[i].length();
pos_old_string = txtFile.contents[i].find(old_string,start_from);
//the position of the old_string in the string.
if(pos_old_string == -1)
{
exit=true;
}
else
{
if(new_string.empty())
{
txtFile.contents[i].replace(pos_old_string,old_string_length,"");
start_from = 0;
}
else
{
txtFile.contents[i].replace(pos_old_string,old_string_length,new_string);
if(txtFile.contents[i].at(pos_old_string + new_string_length - 1) == '')
{
check = false;
}
else
{
start_from = pos_old_string + new_string_length;
}
}
}
}
if(txtFile.contents[i] != the_original_string)
cout<<"Text from current line: "<<endl
<<"[1;36m>[0m "<<txtFile.contents[i]<<endl;
}
void Type(file &txtFile, int type_number) // prints to the screen.
{
int i;
int otherCounter=0;
bool exit=false;
type_number=fabs(type_number);
if(type_number==0)
{
type_number = 1;
}
if(txtFile.currLnInx<=0)
{
txtFile.currLnInx=0;
}
i=txtFile.currLnInx;
while(i<=txtFile.currLnInx+type_number-1 and exit !=true)
{
if(i<= txtFile.tot-1)
{
cout<<"[1;36m>[0m "<<txtFile.contents[i]<<endl;
i++;
}
else
{
cout<<"[1;31m-End of document.-[0m "<<endl;
exit = true;
}
}
txtFile.currLnInx=i-1;
}
void Copy(file txtFile, string copyQue[], int ©Number) // copies text
{
int i;
copyNumber=fabs(copyNumber);
if(copyNumber==0)
{
copyNumber = 1;
}
while(copyNumber+txtFile.currLnInx-1>=txtFile.tot)
{
copyNumber--;
}
for(i=0; i<=copyNumber-1; i++)
{
copyQue[i]="";
}
for(i=0; i<=copyNumber-1; i++)
{
copyQue[i]=txtFile.contents[i+txtFile.currLnInx];
}
}
void Paste(file &txtFile, string copyQue[], int copyNumber, int pasteNumber) // pastes text
{
int i, ii;
for(ii=0; ii<=pasteNumber-1; ii++)
{
if(copyNumber+txtFile.tot-1>=MAX)
{
cout<<"[1;31m-You cannot exceed the tot number of lines.- [0m"<<endl;
}
else
{
for(i=txtFile.tot-1; i>=txtFile.currLnInx+1; i--)
{
txtFile.contents[i+copyNumber]=txtFile.contents[i];
}
for(i=txtFile.currLnInx+1; i<=txtFile.currLnInx+copyNumber; i++)
{
txtFile.contents[i]=copyQue[i-txtFile.currLnInx-1];
}
txtFile.tot=txtFile.tot+copyNumber;
txtFile.currLnInx=i-1;
}
}
}
void Locate(file &txtFile, string inputString) // finds text.
{
int firstPosition, secondPosition, found, i=txtFile.currLnInx;
char indicator;
// Locate works with all characters, not just '/'
indicator = inputString.at(inputString.length()-1);
string tempOne, searchString;
firstPosition = inputString.find(indicator);
tempOne = inputString.substr(firstPosition + 1);
secondPosition = tempOne.find(indicator);
searchString = tempOne.substr(0, secondPosition);
found = -1;
while(found == -1 and i<=txtFile.tot)
{
found=txtFile.contents[i].find(searchString);
i++;
}
if(found == -1)
{
cout<<"[1;31m-No instance of '"<<searchString<<"' was found.-[1;31m "<<endl;
}
else
{
txtFile.currLnInx=i-1;
}
cout<<"[1;36m>[0m "<<txtFile.contents[txtFile.currLnInx]<<endl;
}
void Insert(file &txtFile, int insert_number) // inserts text
{
int i, reductionDifference=0;
bool reduction=false;
insert_number=fabs(insert_number);
if(insert_number==0)
{
insert_number=1;
}
if(txtFile.tot==0 and txtFile.currLnInx<=0)
{
txtFile.currLnInx=-1;
}
while(txtFile.currLnInx+insert_number-1>=MAX-1)
{
insert_number--;
reduction=true;
}
if(reduction==true and insert_number>=1)
{
cout<<"[1;31m-You may only add "<<insert_number
<<" more lines.-[1;31m "<<endl;
}
else if(reduction==true and insert_number<=0)
{
cout<<"[1;31m-You have reached the maximum number of lines.-[1;31m "<<endl;
}
for(i=txtFile.tot-1; i>=txtFile.currLnInx+1; i--)
{
txtFile.contents[i+insert_number]=txtFile.contents[i];
}
for(i=txtFile.currLnInx+1; i<=insert_number+txtFile.currLnInx; i++)
{
cout<<"[1;36m>[0m ";
getline(cin,txtFile.contents[i]);
}
txtFile.tot = txtFile.tot + insert_number;
txtFile.currLnInx = insert_number + txtFile.currLnInx;
}
void Delete(file &txtFile, int delete_number) // deletes text and moves
{ // the other text to the top of the array
int i;
delete_number=fabs(delete_number);
if(delete_number==0)
{
delete_number=1;
}
while(delete_number+txtFile.currLnInx-1>=txtFile.tot)
{
delete_number--;
}
for(i=txtFile.currLnInx+delete_number; i<=txtFile.tot-1; i++)
{
txtFile.contents[i-delete_number]=txtFile.contents[i];
}
while(txtFile.tot<=0)
{
txtFile.tot++;
}
txtFile.tot = txtFile.tot - delete_number;
if(txtFile.currLnInx==txtFile.tot)
{
txtFile.currLnInx--;
}
}
void Replace(file &txtFile, int replace_number) // replaces text
{
int i;
bool reduced;
replace_number=fabs(replace_number);
if(replace_number==0)
{
replace_number=1;
}
if(txtFile.currLnInx==-1)
{
txtFile.currLnInx=0;
}
while(replace_number+txtFile.currLnInx-1>=txtFile.tot)
{
replace_number--;
reduced=true;
}
if(replace_number<=0 and reduced==true)
{
cout<<"[1;31m-You cannot replace lines that do not exist.-[0m"<<endl;
}
for(i=txtFile.currLnInx; i<=txtFile.currLnInx+replace_number-1; i++)
{
cout<<"[1;36m>[0m ";
getline(cin,txtFile.contents[i]);
}
if(reduced==true)
{
cout<<"[1;31m-No more replaceable lines exist past this point.-[0m"<<endl;
}
if(txtFile.currLnInx+replace_number>=txtFile.tot)
{
txtFile.tot=txtFile.currLnInx+replace_number;
}
txtFile.currLnInx=txtFile.currLnInx+replace_number-1;
}
void Move(file &txtFile, int move_number) // moves text
{
if(txtFile.currLnInx + move_number <= -1)
{
txtFile.currLnInx = 0;
}
else if(txtFile.currLnInx + move_number >= txtFile.tot)
{
txtFile.currLnInx = txtFile.tot-1;
}
else
{
txtFile.currLnInx = txtFile.currLnInx + move_number;
}
cout<<"Text from current line: "<<endl<<"[1;36m>[0m "<<txtFile.contents[txtFile.currLnInx]<<endl;
}
void Quit(file txtFile) // Quit function uses recusion to make sure the user does not
// accidently make a typo when answering "would you like to save first"
// and lose their work because of it.
{
string yesNo;
char yesNoTemp;
cout<<"You have asked to quit, "
<<"would you like to save first? "
<< endl;
getline(cin, yesNo);
if(yesNo == "")
{
cout<<"[1;31m-You didn't enter a command.-[0m "<<endl;
Quit(txtFile);
}
else
{
yesNoTemp=yesNo.at(0);
yesNoTemp=toupper(yesNoTemp);
switch(yesNoTemp)
{
case 'Y':
Save(txtFile);
break;
case '*':
Save(txtFile);
break;
case 'S':
Save(txtFile);
break;
case 'N':
cout<<"Your file [1;31mHAS NOT[0m been saved. "<<endl;
break;
default:
cout<<"Saving is serious business and "
<< "[1;31m'"<<yesNo<<"'[0m"
<<" is not an appropriate response. "<<endl
<<"Please enter an appropriate response. "<<endl;
Quit(txtFile);
break;
}
}
}