#include
#include
#include
#include
#include "textFile.hpp"
using namespace std;
void displayHelp();
bool isInteger(const string &s);
bool askSave();
int main(int argc, const char * argv[]) {
int resultCode = 0;
// Convert to a vector.
vector args(argv, argv + argc);
// Process arguments, must be 1 argument, otherwise exit with code 1.
if (args.size() < 2) {
cout << "Missing command line argument!" << endl;
cout << "Usage: ./myEditor " << endl;
resultCode = 1;
} else {
string fileName = args[1];
textFile dataFile(fileName);
// Check if the file is ok to use, if it is, lets go.
if (!dataFile.checkFile()) {
resultCode = 2;
} else {
// We can now assume the file is good, so we can work with it.
dataFile.loadFile();
// Display some text to help the user.
displayHelp();
// Now get user input.
bool done = false;
string userInput = "";
while (!done) {
cout << "> ";
getline(cin, userInput);
char cmd = tolower(userInput.c_str()[0]);
char cmd2 = ' ';
if (userInput.size() > 1) {
cmd2 = userInput.c_str()[1];
}
// This check makes sure the command format is correct
// so that commands don't fire off by mistake.
if (strncmp(&cmd, " ", 1) != 0 && strncmp(&cmd2, " ", 1) == 0) {
switch(cmd) {
case 'q': {
done = true;
break;
}
case 'i': {
unsigned long lineIndex = dataFile.textLines() + 1;
string newLine;
if (userInput.size() > 1) {
string cmdArg = userInput.substr(2);
lineIndex = stol(cmdArg);
}
cout << to_string(lineIndex) << "> ";
getline(cin, newLine);
dataFile.insertLine(lineIndex - 1, newLine);
break;
}
case 'd': {
if (userInput.size() > 1) {
unsigned long lineIndex;
string cmdArg = userInput.substr(2);
lineIndex = stol(cmdArg);
dataFile.removeLine(lineIndex - 1);
}
break;
}
case 'l': {
for (int x = 0; x < dataFile.textLines(); x++) {
cout << to_string(x + 1) << "> " << dataFile.getLine(x) << endl;
}
break;
}
case 'h': {
displayHelp();
break;
}
case 's': {
dataFile.saveFile();
break;
}
}
}
}
// Ask about saving the file before exiting.
bool save = askSave();
if (save) {
dataFile.saveFile();
}
cout << "Thank you for using myEditor." << endl;
}
}
return resultCode;
}
/*
Asks the user if they'd like to save or not, returns true if they do. Anything
other than "y" or "Y" will be interpreted as a negative answer.
*/
bool askSave()
{
bool result = false;
string userInput = "";
cout << "Do you wan to save the change? (Y - yes; N - no) ";
getline(cin, userInput);
userInput = tolower(*userInput.c_str());
if (strncmp(userInput.c_str(), "y", 1) == 0) {
result = true;
}
return result;
}
/*
Displays help text.
*/
void displayHelp()
{
cout << "Welcome to my text editor." << endl;
cout << "tTo insert text at the end of the file, type 'I'" << endl;
cout << "followed by the text." << endl;
cout << "tTo insert text at a certain line number, type 'I'" << endl;
cout << "followed by a space and the desired line number." << endl;
cout << "tTo delete a line, type 'D' followed by a space and the" << endl;
cout << "line number." << endl;
cout << "tTo print all the lines, type 'L' and press enter." << endl;
cout << "tTo save the current content, type 'S' and press enter." << endl;
cout << "tTo display this introduction, type 'H' and press" << endl;
cout << "enter." << endl;
cout << "tTo quit, type 'Q' and press enter." << endl;
}
/*
Checks to see if a stirng is an integer, returns true if the string is an
integer, returns false it it is not.
*/
bool isInteger(const string &s)
{
char *p;
strtol(s.c_str(), &p, 10);
return (*p == 0);
}
textFile.hpp
#ifndef textFile_hpp
#define textFile_hpp
#include
#include
#include "simpleList.hpp"
using namespace std;
class textFile {
private:
simpleList lines; // Stores all lines of the file.
string fileName; // The name of the file being accessed.
ifstream inputHandle; // File object for reading data from the file.
ofstream outputHandle; // File object for writing data to the file.
public:
textFile(); // Default Constructor
textFile(string file); // Constructor
~textFile(); // Destructor
unsigned long textLines(); // Size of the text file in # of lines.
string getLine(unsigned long lineNumber); // One line of text from the file.
void setLine(unsigned long lineNumber, string data); // Sets a specific line to a new value.
void insertLine(unsigned long lineNumber, string data); // Inserts a line into the file.
void removeLine(unsigned long lineNumber); // Removes a line from the file.
bool checkFile(); // Checks to see if a file is good.
void loadFile(); // Loads all the data into the object of the text file in question.
void saveFile(); // Saves all the data in the object back to its file.
void setFile(string file); // Allows setting of the file name after object creation.
string getFile(); // Returns the name of the file being worked with.
};
#endif /* textFile_hpp */
textFile.cpp
#include
#include "textFile.hpp"
#include "simpleList.hpp"
using namespace std;
/*
Default constructor for textFile class.
*/
textFile::textFile()
{
fileName = "";
}
/*
Constructor that accepts the file name in the object creation.
*/
textFile::textFile(string file)
{
fileName = file;
}
/*
Destructor function, no action required at this tiem.
*/
textFile::~textFile()
{
// Nothing for here.
}
unsigned long textFile::textLines()
{
return lines.size();
}
string textFile::getLine(unsigned long lineNumber)
{
// Check to make sure we're not going to go out of bounds.
if (lineNumber < lines.size()) {
lines.toHead();
lines.forward(lineNumber);
return lines.current()->data();
} else {
// If the index of lines to return is out of bounds, return an empty
// string.
string noData = "";
return noData;
}
}
void textFile::setLine(unsigned long lineNumber, string data)
{
if (lines.size() > lineNumber) {
lines.toHead();
lines.forward(lineNumber);
lines.current()->data(data);
} else {
lines.toTail();
lines.current()->data(data);
}
}
/*
Inserts a new line into the lines vector with data.
*/
void textFile::insertLine(unsigned long lineNumber, string data)
{
if (lines.size() > lineNumber) {
lines.toHead();
lines.forward(lineNumber);
lines.insert(data);
} else {
// This will add enough lines to get to lineNumber x even if there are
// not enough lines.
unsigned long blanks = lineNumber - lines.size();
if (blanks > 0) {
string blankString = "";
for (unsigned int x; x < blanks; x++) {
lines.append(blankString);
}
}
lines.append(data);
}
}
/*
Removes a line from the lines vector.
*/
void textFile::removeLine(unsigned long lineNumber)
{
lines.toHead();
lines.forward(lineNumber);
lines.remove();
}
/*
Checks to see if the file is good to read/write from.
*/
bool textFile::checkFile()
{
// Open the file as if we want to read it.
inputHandle.open(fileName);
// Check to see if the file access is good.
bool result = inputHandle.good();
// Close the file.
inputHandle.close();
return result;
}
void textFile::loadFile()
{
// Make sure we start with a blank slate, no items in the vector.
if (lines.size() > 0)
{
lines.clear();
}
// Open up the file for reading.
string line;
inputHandle.open(fileName.c_str());
// Read every line until end of file.
while (!inputHandle.eof()) {
getline(inputHandle, line);
lines.append(line);
}
if (line == "") {
lines.toTail();
lines.remove();
}
// Make sure to close the file again.
inputHandle.close();
}
/*
Saves all lines in the lines vector to the file.
*/
void textFile::saveFile()
{
// Open the file for writing, this should erase an exiting file.
outputHandle.open(fileName.c_str());
// Write every line from the lines vector into the file, appending
// a new line to the end of each.
lines.toHead();
while (lines.current()->next() == nullptr) {
outputHandle << lines.current()->data().c_str() << endl;
lines.forward(1);
}
// Make sure to close the file.
outputHandle.close();
}
void textFile::setFile(string file)
{
fileName = file;
}
/*
Returns the name of the file being worked with.
*/
string textFile::getFile()
{
return fileName;
}
simpleList.cpp
#include
#include "node.hpp"
#include "simpleList.hpp"
using namespace std;
template simpleList::simpleList()
{
head = nullptr;
tail = nullptr;
currentPtr = nullptr;
listSize = 0;
}
template simpleList::~simpleList()
{
clear();
}
// Appends data to the end of the list.
template void simpleList::append(dataType newData)
{
node *newNode = new node;
newNode->container = newData;
if (newNode == nullptr) {
cerr << "Error allocating memory, append failed." << endl;
} else {
if (head == nullptr && tail == nullptr) {
head = newNode;
tail = newNode;
} else {
tail->nextPtr = newNode;
newNode->prevPtr = tail;
tail = newNode;
}
listSize++;
}
}
*/
template void simpleList::insert(dataType newData)
{
if (currentPtr == nullptr) {
currentPtr = head;
}
node *newNode = new node;
newNode->container = newData;
if (newNode == nullptr) {
cerr << "Error allocating memory, insert failed." << endl;
} else if (currentPtr == head) {
head = newNode;
currentPtr->prevPtr = newNode;
newNode->nextPtr = currentPtr;
currentPtr = newNode;
listSize++;
} else {
currentPtr->prevPtr->nextPtr = newNode;
newNode->nextPtr = currentPtr;
newNode->prevPtr = currentPtr->prevPtr;
currentPtr->prevPtr = newNode;
currentPtr = newNode;
listSize++;
}
}
template void simpleList::forward(unsigned long distance)
{
for(int x = 0; x < distance; x++) {
if (currentPtr->nextPtr != nullptr) {
currentPtr = currentPtr->nextPtr;
} else {
break;
}
}
}
template void simpleList::backwward(unsigned long distance)
{
for(int x = 0; x < distance; x++) {
if (currentPtr->prevPtr != nullptr) {
currentPtr = currentPtr->prevPtr;
} else {
break;
}
}
}
// Reset the current pointer back to the beginning of the list.
template void simpleList::toHead()
{
currentPtr = head;
}
// Reset the current pointer to the end of the list.
template void simpleList::toTail()
{
currentPtr = tail;
}
template node *simpleList::find(dataType searchData)
{
node *searchPtr = head;
while (searchPtr->nextPtr != nullptr) {
if (searchData == searchPtr->container) {
currentPtr = searchPtr;
return currentPtr;
}
}
return nullptr;
}
template void simpleList::remove()
{
if (currentPtr == nullptr) {
currentPtr = tail;
}
node *toRemove = currentPtr;
if (currentPtr == tail && currentPtr == head) {
tail = nullptr;
head = nullptr;
currentPtr = nullptr;
} else if (currentPtr == tail) {
tail = currentPtr->prevPtr;
tail->nextPtr = nullptr;
currentPtr = tail;
} else if (currentPtr == head) {
head = currentPtr->nextPtr;
head->prevPtr = nullptr;
currentPtr = head;
} else {
currentPtr->prevPtr->nextPtr = currentPtr->nextPtr;
currentPtr->nextPtr->prevPtr = currentPtr->prevPtr;
currentPtr = currentPtr->prevPtr;
}
delete toRemove;
listSize--;
}
// Removes all items from memory.
template void simpleList::clear()
{
if (listSize > 0 && head != nullptr && tail != nullptr) {
currentPtr = head;
while (listSize > 0) {
remove();
}
}
}
// Give the current size of the list.
template unsigned long simpleList::size()
{
return listSize;
}
// Return the current pointer.
template node *simpleList::current()
{
return currentPtr;
}
simpleList.hpp
#ifndef simpleList_hpp
#define simpleList_hpp
#include "node.hpp"
namespace std {
using namespace std;
template
class simpleList {
private:
node *head;
node *tail;
node *currentPtr;
unsigned long listSize;
public:
simpleList();
~simpleList();
void append(dataType newData);
void insert(dataType newData);
void forward(unsigned long distance);
void backwward(unsigned long distance);
void toHead();
void toTail();
node *find(dataType searchData);
void remove();
void clear();
unsigned long size();
node *current();
};
}
#endif /* simpleList_hpp */
node.cpp
#include "node.hpp"
using namespace std;
template node::node()
{
prevPtr = nullptr;
nextPtr = nullptr;
}
template node::node(node *prv, node *nxt)
{
prevPtr = prv;
nextPtr = nxt;
}
template node *node::prev()
{
return prevPtr;
}
template node *node::next()
{
return nextPtr;
}
/*
Returns the data contents of the node.
*/
template dataType node::data()
{
return container;
}
/*
Stores new data in the node, replacing the old data.
*/
template void node::data(dataType newData)
{
container = newData;
}
node.hpp
#ifndef node_hpp
#define node_hpp
namespace std {
template
class node {
template friend class simpleList;
private:
node *prevPtr;
node *nextPtr;
dataType container;
public:
node(); // Create a new, blank, node.
node(node *prv, node *nxt); // Create a new node with pointers.
~node(); // Destroy the node.
node *next(); // Returns the next object pointer
node *prev(); // Returns the previous object pointer
dataType data(); // Returns the nodes data.
void data(dataType); // Stores data in the node.
};
}
#endif /* node_hpp */
data.txt
The first line
The second line
And another line
One more line
what do you try to type here?
I like sugar cookies
This line is boring......
This is the last line
Solution
#include
#include
#include
#include
#include "textFile.hpp"
using namespace std;
void displayHelp();
bool isInteger(const string &s);
bool askSave();
int main(int argc, const char * argv[]) {
int resultCode = 0;
// Convert to a vector.
vector args(argv, argv + argc);
// Process arguments, must be 1 argument, otherwise exit with code 1.
if (args.size() < 2) {
cout << "Missing command line argument!" << endl;
cout << "Usage: ./myEditor " << endl;
resultCode = 1;
} else {
string fileName = args[1];
textFile dataFile(fileName);
// Check if the file is ok to use, if it is, lets go.
if (!dataFile.checkFile()) {
resultCode = 2;
} else {
// We can now assume the file is good, so we can work with it.
dataFile.loadFile();
// Display some text to help the user.
displayHelp();
// Now get user input.
bool done = false;
string userInput = "";
while (!done) {
cout << "> ";
getline(cin, userInput);
char cmd = tolower(userInput.c_str()[0]);
char cmd2 = ' ';
if (userInput.size() > 1) {
cmd2 = userInput.c_str()[1];
}
// This check makes sure the command format is correct
// so that commands don't fire off by mistake.
if (strncmp(&cmd, " ", 1) != 0 && strncmp(&cmd2, " ", 1) == 0) {
switch(cmd) {
case 'q': {
done = true;
break;
}
case 'i': {
unsigned long lineIndex = dataFile.textLines() + 1;
string newLine;
if (userInput.size() > 1) {
string cmdArg = userInput.substr(2);
lineIndex = stol(cmdArg);
}
cout << to_string(lineIndex) << "> ";
getline(cin, newLine);
dataFile.insertLine(lineIndex - 1, newLine);
break;
}
case 'd': {
if (userInput.size() > 1) {
unsigned long lineIndex;
string cmdArg = userInput.substr(2);
lineIndex = stol(cmdArg);
dataFile.removeLine(lineIndex - 1);
}
break;
}
case 'l': {
for (int x = 0; x < dataFile.textLines(); x++) {
cout << to_string(x + 1) << "> " << dataFile.getLine(x) << endl;
}
break;
}
case 'h': {
displayHelp();
break;
}
case 's': {
dataFile.saveFile();
break;
}
}
}
}
// Ask about saving the file before exiting.
bool save = askSave();
if (save) {
dataFile.saveFile();
}
cout << "Thank you for using myEditor." << endl;
}
}
return resultCode;
}
/*
Asks the user if they'd like to save or not, returns true if they do. Anything
other than "y" or "Y" will be interpreted as a negative answer.
*/
bool askSave()
{
bool result = false;
string userInput = "";
cout << "Do you wan to save the change? (Y - yes; N - no) ";
getline(cin, userInput);
userInput = tolower(*userInput.c_str());
if (strncmp(userInput.c_str(), "y", 1) == 0) {
result = true;
}
return result;
}
/*
Displays help text.
*/
void displayHelp()
{
cout << "Welcome to my text editor." << endl;
cout << "tTo insert text at the end of the file, type 'I'" << endl;
cout << "followed by the text." << endl;
cout << "tTo insert text at a certain line number, type 'I'" << endl;
cout << "followed by a space and the desired line number." << endl;
cout << "tTo delete a line, type 'D' followed by a space and the" << endl;
cout << "line number." << endl;
cout << "tTo print all the lines, type 'L' and press enter." << endl;
cout << "tTo save the current content, type 'S' and press enter." << endl;
cout << "tTo display this introduction, type 'H' and press" << endl;
cout << "enter." << endl;
cout << "tTo quit, type 'Q' and press enter." << endl;
}
/*
Checks to see if a stirng is an integer, returns true if the string is an
integer, returns false it it is not.
*/
bool isInteger(const string &s)
{
char *p;
strtol(s.c_str(), &p, 10);
return (*p == 0);
}
textFile.hpp
#ifndef textFile_hpp
#define textFile_hpp
#include
#include
#include "simpleList.hpp"
using namespace std;
class textFile {
private:
simpleList lines; // Stores all lines of the file.
string fileName; // The name of the file being accessed.
ifstream inputHandle; // File object for reading data from the file.
ofstream outputHandle; // File object for writing data to the file.
public:
textFile(); // Default Constructor
textFile(string file); // Constructor
~textFile(); // Destructor
unsigned long textLines(); // Size of the text file in # of lines.
string getLine(unsigned long lineNumber); // One line of text from the file.
void setLine(unsigned long lineNumber, string data); // Sets a specific line to a new value.
void insertLine(unsigned long lineNumber, string data); // Inserts a line into the file.
void removeLine(unsigned long lineNumber); // Removes a line from the file.
bool checkFile(); // Checks to see if a file is good.
void loadFile(); // Loads all the data into the object of the text file in question.
void saveFile(); // Saves all the data in the object back to its file.
void setFile(string file); // Allows setting of the file name after object creation.
string getFile(); // Returns the name of the file being worked with.
};
#endif /* textFile_hpp */
textFile.cpp
#include
#include "textFile.hpp"
#include "simpleList.hpp"
using namespace std;
/*
Default constructor for textFile class.
*/
textFile::textFile()
{
fileName = "";
}
/*
Constructor that accepts the file name in the object creation.
*/
textFile::textFile(string file)
{
fileName = file;
}
/*
Destructor function, no action required at this tiem.
*/
textFile::~textFile()
{
// Nothing for here.
}
unsigned long textFile::textLines()
{
return lines.size();
}
string textFile::getLine(unsigned long lineNumber)
{
// Check to make sure we're not going to go out of bounds.
if (lineNumber < lines.size()) {
lines.toHead();
lines.forward(lineNumber);
return lines.current()->data();
} else {
// If the index of lines to return is out of bounds, return an empty
// string.
string noData = "";
return noData;
}
}
void textFile::setLine(unsigned long lineNumber, string data)
{
if (lines.size() > lineNumber) {
lines.toHead();
lines.forward(lineNumber);
lines.current()->data(data);
} else {
lines.toTail();
lines.current()->data(data);
}
}
/*
Inserts a new line into the lines vector with data.
*/
void textFile::insertLine(unsigned long lineNumber, string data)
{
if (lines.size() > lineNumber) {
lines.toHead();
lines.forward(lineNumber);
lines.insert(data);
} else {
// This will add enough lines to get to lineNumber x even if there are
// not enough lines.
unsigned long blanks = lineNumber - lines.size();
if (blanks > 0) {
string blankString = "";
for (unsigned int x; x < blanks; x++) {
lines.append(blankString);
}
}
lines.append(data);
}
}
/*
Removes a line from the lines vector.
*/
void textFile::removeLine(unsigned long lineNumber)
{
lines.toHead();
lines.forward(lineNumber);
lines.remove();
}
/*
Checks to see if the file is good to read/write from.
*/
bool textFile::checkFile()
{
// Open the file as if we want to read it.
inputHandle.open(fileName);
// Check to see if the file access is good.
bool result = inputHandle.good();
// Close the file.
inputHandle.close();
return result;
}
void textFile::loadFile()
{
// Make sure we start with a blank slate, no items in the vector.
if (lines.size() > 0)
{
lines.clear();
}
// Open up the file for reading.
string line;
inputHandle.open(fileName.c_str());
// Read every line until end of file.
while (!inputHandle.eof()) {
getline(inputHandle, line);
lines.append(line);
}
if (line == "") {
lines.toTail();
lines.remove();
}
// Make sure to close the file again.
inputHandle.close();
}
/*
Saves all lines in the lines vector to the file.
*/
void textFile::saveFile()
{
// Open the file for writing, this should erase an exiting file.
outputHandle.open(fileName.c_str());
// Write every line from the lines vector into the file, appending
// a new line to the end of each.
lines.toHead();
while (lines.current()->next() == nullptr) {
outputHandle << lines.current()->data().c_str() << endl;
lines.forward(1);
}
// Make sure to close the file.
outputHandle.close();
}
void textFile::setFile(string file)
{
fileName = file;
}
/*
Returns the name of the file being worked with.
*/
string textFile::getFile()
{
return fileName;
}
simpleList.cpp
#include
#include "node.hpp"
#include "simpleList.hpp"
using namespace std;
template simpleList::simpleList()
{
head = nullptr;
tail = nullptr;
currentPtr = nullptr;
listSize = 0;
}
template simpleList::~simpleList()
{
clear();
}
// Appends data to the end of the list.
template void simpleList::append(dataType newData)
{
node *newNode = new node;
newNode->container = newData;
if (newNode == nullptr) {
cerr << "Error allocating memory, append failed." << endl;
} else {
if (head == nullptr && tail == nullptr) {
head = newNode;
tail = newNode;
} else {
tail->nextPtr = newNode;
newNode->prevPtr = tail;
tail = newNode;
}
listSize++;
}
}
*/
template void simpleList::insert(dataType newData)
{
if (currentPtr == nullptr) {
currentPtr = head;
}
node *newNode = new node;
newNode->container = newData;
if (newNode == nullptr) {
cerr << "Error allocating memory, insert failed." << endl;
} else if (currentPtr == head) {
head = newNode;
currentPtr->prevPtr = newNode;
newNode->nextPtr = currentPtr;
currentPtr = newNode;
listSize++;
} else {
currentPtr->prevPtr->nextPtr = newNode;
newNode->nextPtr = currentPtr;
newNode->prevPtr = currentPtr->prevPtr;
currentPtr->prevPtr = newNode;
currentPtr = newNode;
listSize++;
}
}
template void simpleList::forward(unsigned long distance)
{
for(int x = 0; x < distance; x++) {
if (currentPtr->nextPtr != nullptr) {
currentPtr = currentPtr->nextPtr;
} else {
break;
}
}
}
template void simpleList::backwward(unsigned long distance)
{
for(int x = 0; x < distance; x++) {
if (currentPtr->prevPtr != nullptr) {
currentPtr = currentPtr->prevPtr;
} else {
break;
}
}
}
// Reset the current pointer back to the beginning of the list.
template void simpleList::toHead()
{
currentPtr = head;
}
// Reset the current pointer to the end of the list.
template void simpleList::toTail()
{
currentPtr = tail;
}
template node *simpleList::find(dataType searchData)
{
node *searchPtr = head;
while (searchPtr->nextPtr != nullptr) {
if (searchData == searchPtr->container) {
currentPtr = searchPtr;
return currentPtr;
}
}
return nullptr;
}
template void simpleList::remove()
{
if (currentPtr == nullptr) {
currentPtr = tail;
}
node *toRemove = currentPtr;
if (currentPtr == tail && currentPtr == head) {
tail = nullptr;
head = nullptr;
currentPtr = nullptr;
} else if (currentPtr == tail) {
tail = currentPtr->prevPtr;
tail->nextPtr = nullptr;
currentPtr = tail;
} else if (currentPtr == head) {
head = currentPtr->nextPtr;
head->prevPtr = nullptr;
currentPtr = head;
} else {
currentPtr->prevPtr->nextPtr = currentPtr->nextPtr;
currentPtr->nextPtr->prevPtr = currentPtr->prevPtr;
currentPtr = currentPtr->prevPtr;
}
delete toRemove;
listSize--;
}
// Removes all items from memory.
template void simpleList::clear()
{
if (listSize > 0 && head != nullptr && tail != nullptr) {
currentPtr = head;
while (listSize > 0) {
remove();
}
}
}
// Give the current size of the list.
template unsigned long simpleList::size()
{
return listSize;
}
// Return the current pointer.
template node *simpleList::current()
{
return currentPtr;
}
simpleList.hpp
#ifndef simpleList_hpp
#define simpleList_hpp
#include "node.hpp"
namespace std {
using namespace std;
template
class simpleList {
private:
node *head;
node *tail;
node *currentPtr;
unsigned long listSize;
public:
simpleList();
~simpleList();
void append(dataType newData);
void insert(dataType newData);
void forward(unsigned long distance);
void backwward(unsigned long distance);
void toHead();
void toTail();
node *find(dataType searchData);
void remove();
void clear();
unsigned long size();
node *current();
};
}
#endif /* simpleList_hpp */
node.cpp
#include "node.hpp"
using namespace std;
template node::node()
{
prevPtr = nullptr;
nextPtr = nullptr;
}
template node::node(node *prv, node *nxt)
{
prevPtr = prv;
nextPtr = nxt;
}
template node *node::prev()
{
return prevPtr;
}
template node *node::next()
{
return nextPtr;
}
/*
Returns the data contents of the node.
*/
template dataType node::data()
{
return container;
}
/*
Stores new data in the node, replacing the old data.
*/
template void node::data(dataType newData)
{
container = newData;
}
node.hpp
#ifndef node_hpp
#define node_hpp
namespace std {
template
class node {
template friend class simpleList;
private:
node *prevPtr;
node *nextPtr;
dataType container;
public:
node(); // Create a new, blank, node.
node(node *prv, node *nxt); // Create a new node with pointers.
~node(); // Destroy the node.
node *next(); // Returns the next object pointer
node *prev(); // Returns the previous object pointer
dataType data(); // Returns the nodes data.
void data(dataType); // Stores data in the node.
};
}
#endif /* node_hpp */
data.txt
The first line
The second line
And another line
One more line
what do you try to type here?
I like sugar cookies
This line is boring......
This is the last line

#include iostream #include cstring #include vector #i.pdf

  • 1.
    #include #include #include #include #include "textFile.hpp" using namespacestd; void displayHelp(); bool isInteger(const string &s); bool askSave(); int main(int argc, const char * argv[]) { int resultCode = 0; // Convert to a vector. vector args(argv, argv + argc); // Process arguments, must be 1 argument, otherwise exit with code 1. if (args.size() < 2) { cout << "Missing command line argument!" << endl; cout << "Usage: ./myEditor " << endl; resultCode = 1; } else { string fileName = args[1]; textFile dataFile(fileName); // Check if the file is ok to use, if it is, lets go. if (!dataFile.checkFile()) { resultCode = 2; } else { // We can now assume the file is good, so we can work with it. dataFile.loadFile(); // Display some text to help the user. displayHelp();
  • 2.
    // Now getuser input. bool done = false; string userInput = ""; while (!done) { cout << "> "; getline(cin, userInput); char cmd = tolower(userInput.c_str()[0]); char cmd2 = ' '; if (userInput.size() > 1) { cmd2 = userInput.c_str()[1]; } // This check makes sure the command format is correct // so that commands don't fire off by mistake. if (strncmp(&cmd, " ", 1) != 0 && strncmp(&cmd2, " ", 1) == 0) { switch(cmd) { case 'q': { done = true; break; } case 'i': { unsigned long lineIndex = dataFile.textLines() + 1; string newLine; if (userInput.size() > 1) { string cmdArg = userInput.substr(2); lineIndex = stol(cmdArg); } cout << to_string(lineIndex) << "> "; getline(cin, newLine); dataFile.insertLine(lineIndex - 1, newLine); break; } case 'd': { if (userInput.size() > 1) {
  • 3.
    unsigned long lineIndex; stringcmdArg = userInput.substr(2); lineIndex = stol(cmdArg); dataFile.removeLine(lineIndex - 1); } break; } case 'l': { for (int x = 0; x < dataFile.textLines(); x++) { cout << to_string(x + 1) << "> " << dataFile.getLine(x) << endl; } break; } case 'h': { displayHelp(); break; } case 's': { dataFile.saveFile(); break; } } } } // Ask about saving the file before exiting. bool save = askSave(); if (save) { dataFile.saveFile(); } cout << "Thank you for using myEditor." << endl; } } return resultCode; }
  • 4.
    /* Asks the userif they'd like to save or not, returns true if they do. Anything other than "y" or "Y" will be interpreted as a negative answer. */ bool askSave() { bool result = false; string userInput = ""; cout << "Do you wan to save the change? (Y - yes; N - no) "; getline(cin, userInput); userInput = tolower(*userInput.c_str()); if (strncmp(userInput.c_str(), "y", 1) == 0) { result = true; } return result; } /* Displays help text. */ void displayHelp() { cout << "Welcome to my text editor." << endl; cout << "tTo insert text at the end of the file, type 'I'" << endl; cout << "followed by the text." << endl; cout << "tTo insert text at a certain line number, type 'I'" << endl; cout << "followed by a space and the desired line number." << endl; cout << "tTo delete a line, type 'D' followed by a space and the" << endl; cout << "line number." << endl; cout << "tTo print all the lines, type 'L' and press enter." << endl; cout << "tTo save the current content, type 'S' and press enter." << endl; cout << "tTo display this introduction, type 'H' and press" << endl; cout << "enter." << endl; cout << "tTo quit, type 'Q' and press enter." << endl; } /* Checks to see if a stirng is an integer, returns true if the string is an
  • 5.
    integer, returns falseit it is not. */ bool isInteger(const string &s) { char *p; strtol(s.c_str(), &p, 10); return (*p == 0); } textFile.hpp #ifndef textFile_hpp #define textFile_hpp #include #include #include "simpleList.hpp" using namespace std; class textFile { private: simpleList lines; // Stores all lines of the file. string fileName; // The name of the file being accessed. ifstream inputHandle; // File object for reading data from the file. ofstream outputHandle; // File object for writing data to the file. public: textFile(); // Default Constructor textFile(string file); // Constructor ~textFile(); // Destructor unsigned long textLines(); // Size of the text file in # of lines. string getLine(unsigned long lineNumber); // One line of text from the file. void setLine(unsigned long lineNumber, string data); // Sets a specific line to a new value. void insertLine(unsigned long lineNumber, string data); // Inserts a line into the file. void removeLine(unsigned long lineNumber); // Removes a line from the file. bool checkFile(); // Checks to see if a file is good. void loadFile(); // Loads all the data into the object of the text file in question. void saveFile(); // Saves all the data in the object back to its file. void setFile(string file); // Allows setting of the file name after object creation. string getFile(); // Returns the name of the file being worked with. };
  • 6.
    #endif /* textFile_hpp*/ textFile.cpp #include #include "textFile.hpp" #include "simpleList.hpp" using namespace std; /* Default constructor for textFile class. */ textFile::textFile() { fileName = ""; } /* Constructor that accepts the file name in the object creation. */ textFile::textFile(string file) { fileName = file; } /* Destructor function, no action required at this tiem. */ textFile::~textFile() { // Nothing for here. } unsigned long textFile::textLines() { return lines.size(); } string textFile::getLine(unsigned long lineNumber) { // Check to make sure we're not going to go out of bounds. if (lineNumber < lines.size()) {
  • 7.
    lines.toHead(); lines.forward(lineNumber); return lines.current()->data(); } else{ // If the index of lines to return is out of bounds, return an empty // string. string noData = ""; return noData; } } void textFile::setLine(unsigned long lineNumber, string data) { if (lines.size() > lineNumber) { lines.toHead(); lines.forward(lineNumber); lines.current()->data(data); } else { lines.toTail(); lines.current()->data(data); } } /* Inserts a new line into the lines vector with data. */ void textFile::insertLine(unsigned long lineNumber, string data) { if (lines.size() > lineNumber) { lines.toHead(); lines.forward(lineNumber); lines.insert(data); } else { // This will add enough lines to get to lineNumber x even if there are // not enough lines. unsigned long blanks = lineNumber - lines.size(); if (blanks > 0) { string blankString = "";
  • 8.
    for (unsigned intx; x < blanks; x++) { lines.append(blankString); } } lines.append(data); } } /* Removes a line from the lines vector. */ void textFile::removeLine(unsigned long lineNumber) { lines.toHead(); lines.forward(lineNumber); lines.remove(); } /* Checks to see if the file is good to read/write from. */ bool textFile::checkFile() { // Open the file as if we want to read it. inputHandle.open(fileName); // Check to see if the file access is good. bool result = inputHandle.good(); // Close the file. inputHandle.close(); return result; } void textFile::loadFile() { // Make sure we start with a blank slate, no items in the vector. if (lines.size() > 0) { lines.clear(); }
  • 9.
    // Open upthe file for reading. string line; inputHandle.open(fileName.c_str()); // Read every line until end of file. while (!inputHandle.eof()) { getline(inputHandle, line); lines.append(line); } if (line == "") { lines.toTail(); lines.remove(); } // Make sure to close the file again. inputHandle.close(); } /* Saves all lines in the lines vector to the file. */ void textFile::saveFile() { // Open the file for writing, this should erase an exiting file. outputHandle.open(fileName.c_str()); // Write every line from the lines vector into the file, appending // a new line to the end of each. lines.toHead(); while (lines.current()->next() == nullptr) { outputHandle << lines.current()->data().c_str() << endl; lines.forward(1); } // Make sure to close the file. outputHandle.close(); } void textFile::setFile(string file) { fileName = file;
  • 10.
    } /* Returns the nameof the file being worked with. */ string textFile::getFile() { return fileName; } simpleList.cpp #include #include "node.hpp" #include "simpleList.hpp" using namespace std; template simpleList::simpleList() { head = nullptr; tail = nullptr; currentPtr = nullptr; listSize = 0; } template simpleList::~simpleList() { clear(); } // Appends data to the end of the list. template void simpleList::append(dataType newData) { node *newNode = new node; newNode->container = newData; if (newNode == nullptr) { cerr << "Error allocating memory, append failed." << endl; } else { if (head == nullptr && tail == nullptr) { head = newNode;
  • 11.
    tail = newNode; }else { tail->nextPtr = newNode; newNode->prevPtr = tail; tail = newNode; } listSize++; } } */ template void simpleList::insert(dataType newData) { if (currentPtr == nullptr) { currentPtr = head; } node *newNode = new node; newNode->container = newData; if (newNode == nullptr) { cerr << "Error allocating memory, insert failed." << endl; } else if (currentPtr == head) { head = newNode; currentPtr->prevPtr = newNode; newNode->nextPtr = currentPtr; currentPtr = newNode; listSize++; } else { currentPtr->prevPtr->nextPtr = newNode; newNode->nextPtr = currentPtr; newNode->prevPtr = currentPtr->prevPtr; currentPtr->prevPtr = newNode; currentPtr = newNode; listSize++; } } template void simpleList::forward(unsigned long distance)
  • 12.
    { for(int x =0; x < distance; x++) { if (currentPtr->nextPtr != nullptr) { currentPtr = currentPtr->nextPtr; } else { break; } } } template void simpleList::backwward(unsigned long distance) { for(int x = 0; x < distance; x++) { if (currentPtr->prevPtr != nullptr) { currentPtr = currentPtr->prevPtr; } else { break; } } } // Reset the current pointer back to the beginning of the list. template void simpleList::toHead() { currentPtr = head; } // Reset the current pointer to the end of the list. template void simpleList::toTail() { currentPtr = tail; } template node *simpleList::find(dataType searchData) { node *searchPtr = head; while (searchPtr->nextPtr != nullptr) { if (searchData == searchPtr->container) { currentPtr = searchPtr;
  • 13.
    return currentPtr; } } return nullptr; } templatevoid simpleList::remove() { if (currentPtr == nullptr) { currentPtr = tail; } node *toRemove = currentPtr; if (currentPtr == tail && currentPtr == head) { tail = nullptr; head = nullptr; currentPtr = nullptr; } else if (currentPtr == tail) { tail = currentPtr->prevPtr; tail->nextPtr = nullptr; currentPtr = tail; } else if (currentPtr == head) { head = currentPtr->nextPtr; head->prevPtr = nullptr; currentPtr = head; } else { currentPtr->prevPtr->nextPtr = currentPtr->nextPtr; currentPtr->nextPtr->prevPtr = currentPtr->prevPtr; currentPtr = currentPtr->prevPtr; } delete toRemove; listSize--; } // Removes all items from memory.
  • 14.
    template void simpleList::clear() { if(listSize > 0 && head != nullptr && tail != nullptr) { currentPtr = head; while (listSize > 0) { remove(); } } } // Give the current size of the list. template unsigned long simpleList::size() { return listSize; } // Return the current pointer. template node *simpleList::current() { return currentPtr; } simpleList.hpp #ifndef simpleList_hpp #define simpleList_hpp #include "node.hpp" namespace std { using namespace std; template class simpleList { private: node *head; node *tail; node *currentPtr; unsigned long listSize; public:
  • 15.
    simpleList(); ~simpleList(); void append(dataType newData); voidinsert(dataType newData); void forward(unsigned long distance); void backwward(unsigned long distance); void toHead(); void toTail(); node *find(dataType searchData); void remove(); void clear(); unsigned long size(); node *current(); }; } #endif /* simpleList_hpp */ node.cpp #include "node.hpp" using namespace std; template node::node() { prevPtr = nullptr; nextPtr = nullptr; } template node::node(node *prv, node *nxt) { prevPtr = prv; nextPtr = nxt; } template node *node::prev() { return prevPtr; } template node *node::next()
  • 16.
    { return nextPtr; } /* Returns thedata contents of the node. */ template dataType node::data() { return container; } /* Stores new data in the node, replacing the old data. */ template void node::data(dataType newData) { container = newData; } node.hpp #ifndef node_hpp #define node_hpp namespace std { template class node { template friend class simpleList; private: node *prevPtr; node *nextPtr; dataType container; public: node(); // Create a new, blank, node. node(node *prv, node *nxt); // Create a new node with pointers. ~node(); // Destroy the node. node *next(); // Returns the next object pointer node *prev(); // Returns the previous object pointer dataType data(); // Returns the nodes data.
  • 17.
    void data(dataType); //Stores data in the node. }; } #endif /* node_hpp */ data.txt The first line The second line And another line One more line what do you try to type here? I like sugar cookies This line is boring...... This is the last line Solution #include #include #include #include #include "textFile.hpp" using namespace std; void displayHelp(); bool isInteger(const string &s); bool askSave(); int main(int argc, const char * argv[]) { int resultCode = 0; // Convert to a vector. vector args(argv, argv + argc); // Process arguments, must be 1 argument, otherwise exit with code 1. if (args.size() < 2) { cout << "Missing command line argument!" << endl; cout << "Usage: ./myEditor " << endl;
  • 18.
    resultCode = 1; }else { string fileName = args[1]; textFile dataFile(fileName); // Check if the file is ok to use, if it is, lets go. if (!dataFile.checkFile()) { resultCode = 2; } else { // We can now assume the file is good, so we can work with it. dataFile.loadFile(); // Display some text to help the user. displayHelp(); // Now get user input. bool done = false; string userInput = ""; while (!done) { cout << "> "; getline(cin, userInput); char cmd = tolower(userInput.c_str()[0]); char cmd2 = ' '; if (userInput.size() > 1) { cmd2 = userInput.c_str()[1]; } // This check makes sure the command format is correct // so that commands don't fire off by mistake. if (strncmp(&cmd, " ", 1) != 0 && strncmp(&cmd2, " ", 1) == 0) { switch(cmd) { case 'q': { done = true; break;
  • 19.
    } case 'i': { unsignedlong lineIndex = dataFile.textLines() + 1; string newLine; if (userInput.size() > 1) { string cmdArg = userInput.substr(2); lineIndex = stol(cmdArg); } cout << to_string(lineIndex) << "> "; getline(cin, newLine); dataFile.insertLine(lineIndex - 1, newLine); break; } case 'd': { if (userInput.size() > 1) { unsigned long lineIndex; string cmdArg = userInput.substr(2); lineIndex = stol(cmdArg); dataFile.removeLine(lineIndex - 1); } break; } case 'l': { for (int x = 0; x < dataFile.textLines(); x++) { cout << to_string(x + 1) << "> " << dataFile.getLine(x) << endl; } break; } case 'h': { displayHelp(); break; } case 's': { dataFile.saveFile(); break; }
  • 20.
    } } } // Ask aboutsaving the file before exiting. bool save = askSave(); if (save) { dataFile.saveFile(); } cout << "Thank you for using myEditor." << endl; } } return resultCode; } /* Asks the user if they'd like to save or not, returns true if they do. Anything other than "y" or "Y" will be interpreted as a negative answer. */ bool askSave() { bool result = false; string userInput = ""; cout << "Do you wan to save the change? (Y - yes; N - no) "; getline(cin, userInput); userInput = tolower(*userInput.c_str()); if (strncmp(userInput.c_str(), "y", 1) == 0) { result = true; } return result; } /* Displays help text. */ void displayHelp() {
  • 21.
    cout << "Welcometo my text editor." << endl; cout << "tTo insert text at the end of the file, type 'I'" << endl; cout << "followed by the text." << endl; cout << "tTo insert text at a certain line number, type 'I'" << endl; cout << "followed by a space and the desired line number." << endl; cout << "tTo delete a line, type 'D' followed by a space and the" << endl; cout << "line number." << endl; cout << "tTo print all the lines, type 'L' and press enter." << endl; cout << "tTo save the current content, type 'S' and press enter." << endl; cout << "tTo display this introduction, type 'H' and press" << endl; cout << "enter." << endl; cout << "tTo quit, type 'Q' and press enter." << endl; } /* Checks to see if a stirng is an integer, returns true if the string is an integer, returns false it it is not. */ bool isInteger(const string &s) { char *p; strtol(s.c_str(), &p, 10); return (*p == 0); } textFile.hpp #ifndef textFile_hpp #define textFile_hpp #include #include #include "simpleList.hpp" using namespace std; class textFile { private: simpleList lines; // Stores all lines of the file. string fileName; // The name of the file being accessed. ifstream inputHandle; // File object for reading data from the file. ofstream outputHandle; // File object for writing data to the file.
  • 22.
    public: textFile(); // DefaultConstructor textFile(string file); // Constructor ~textFile(); // Destructor unsigned long textLines(); // Size of the text file in # of lines. string getLine(unsigned long lineNumber); // One line of text from the file. void setLine(unsigned long lineNumber, string data); // Sets a specific line to a new value. void insertLine(unsigned long lineNumber, string data); // Inserts a line into the file. void removeLine(unsigned long lineNumber); // Removes a line from the file. bool checkFile(); // Checks to see if a file is good. void loadFile(); // Loads all the data into the object of the text file in question. void saveFile(); // Saves all the data in the object back to its file. void setFile(string file); // Allows setting of the file name after object creation. string getFile(); // Returns the name of the file being worked with. }; #endif /* textFile_hpp */ textFile.cpp #include #include "textFile.hpp" #include "simpleList.hpp" using namespace std; /* Default constructor for textFile class. */ textFile::textFile() { fileName = ""; } /* Constructor that accepts the file name in the object creation. */ textFile::textFile(string file) { fileName = file; }
  • 23.
    /* Destructor function, noaction required at this tiem. */ textFile::~textFile() { // Nothing for here. } unsigned long textFile::textLines() { return lines.size(); } string textFile::getLine(unsigned long lineNumber) { // Check to make sure we're not going to go out of bounds. if (lineNumber < lines.size()) { lines.toHead(); lines.forward(lineNumber); return lines.current()->data(); } else { // If the index of lines to return is out of bounds, return an empty // string. string noData = ""; return noData; } } void textFile::setLine(unsigned long lineNumber, string data) { if (lines.size() > lineNumber) { lines.toHead(); lines.forward(lineNumber); lines.current()->data(data); } else { lines.toTail(); lines.current()->data(data); } }
  • 24.
    /* Inserts a newline into the lines vector with data. */ void textFile::insertLine(unsigned long lineNumber, string data) { if (lines.size() > lineNumber) { lines.toHead(); lines.forward(lineNumber); lines.insert(data); } else { // This will add enough lines to get to lineNumber x even if there are // not enough lines. unsigned long blanks = lineNumber - lines.size(); if (blanks > 0) { string blankString = ""; for (unsigned int x; x < blanks; x++) { lines.append(blankString); } } lines.append(data); } } /* Removes a line from the lines vector. */ void textFile::removeLine(unsigned long lineNumber) { lines.toHead(); lines.forward(lineNumber); lines.remove(); } /* Checks to see if the file is good to read/write from. */ bool textFile::checkFile() {
  • 25.
    // Open thefile as if we want to read it. inputHandle.open(fileName); // Check to see if the file access is good. bool result = inputHandle.good(); // Close the file. inputHandle.close(); return result; } void textFile::loadFile() { // Make sure we start with a blank slate, no items in the vector. if (lines.size() > 0) { lines.clear(); } // Open up the file for reading. string line; inputHandle.open(fileName.c_str()); // Read every line until end of file. while (!inputHandle.eof()) { getline(inputHandle, line); lines.append(line); } if (line == "") { lines.toTail(); lines.remove(); } // Make sure to close the file again. inputHandle.close(); } /* Saves all lines in the lines vector to the file. */ void textFile::saveFile() {
  • 26.
    // Open thefile for writing, this should erase an exiting file. outputHandle.open(fileName.c_str()); // Write every line from the lines vector into the file, appending // a new line to the end of each. lines.toHead(); while (lines.current()->next() == nullptr) { outputHandle << lines.current()->data().c_str() << endl; lines.forward(1); } // Make sure to close the file. outputHandle.close(); } void textFile::setFile(string file) { fileName = file; } /* Returns the name of the file being worked with. */ string textFile::getFile() { return fileName; } simpleList.cpp #include #include "node.hpp" #include "simpleList.hpp" using namespace std; template simpleList::simpleList() { head = nullptr; tail = nullptr; currentPtr = nullptr; listSize = 0;
  • 27.
    } template simpleList::~simpleList() { clear(); } // Appendsdata to the end of the list. template void simpleList::append(dataType newData) { node *newNode = new node; newNode->container = newData; if (newNode == nullptr) { cerr << "Error allocating memory, append failed." << endl; } else { if (head == nullptr && tail == nullptr) { head = newNode; tail = newNode; } else { tail->nextPtr = newNode; newNode->prevPtr = tail; tail = newNode; } listSize++; } } */ template void simpleList::insert(dataType newData) { if (currentPtr == nullptr) { currentPtr = head; } node *newNode = new node; newNode->container = newData; if (newNode == nullptr) { cerr << "Error allocating memory, insert failed." << endl; } else if (currentPtr == head) {
  • 28.
    head = newNode; currentPtr->prevPtr= newNode; newNode->nextPtr = currentPtr; currentPtr = newNode; listSize++; } else { currentPtr->prevPtr->nextPtr = newNode; newNode->nextPtr = currentPtr; newNode->prevPtr = currentPtr->prevPtr; currentPtr->prevPtr = newNode; currentPtr = newNode; listSize++; } } template void simpleList::forward(unsigned long distance) { for(int x = 0; x < distance; x++) { if (currentPtr->nextPtr != nullptr) { currentPtr = currentPtr->nextPtr; } else { break; } } } template void simpleList::backwward(unsigned long distance) { for(int x = 0; x < distance; x++) { if (currentPtr->prevPtr != nullptr) { currentPtr = currentPtr->prevPtr; } else { break; } } } // Reset the current pointer back to the beginning of the list. template void simpleList::toHead()
  • 29.
    { currentPtr = head; } //Reset the current pointer to the end of the list. template void simpleList::toTail() { currentPtr = tail; } template node *simpleList::find(dataType searchData) { node *searchPtr = head; while (searchPtr->nextPtr != nullptr) { if (searchData == searchPtr->container) { currentPtr = searchPtr; return currentPtr; } } return nullptr; } template void simpleList::remove() { if (currentPtr == nullptr) { currentPtr = tail; } node *toRemove = currentPtr; if (currentPtr == tail && currentPtr == head) { tail = nullptr; head = nullptr; currentPtr = nullptr; } else if (currentPtr == tail) { tail = currentPtr->prevPtr; tail->nextPtr = nullptr;
  • 30.
    currentPtr = tail; }else if (currentPtr == head) { head = currentPtr->nextPtr; head->prevPtr = nullptr; currentPtr = head; } else { currentPtr->prevPtr->nextPtr = currentPtr->nextPtr; currentPtr->nextPtr->prevPtr = currentPtr->prevPtr; currentPtr = currentPtr->prevPtr; } delete toRemove; listSize--; } // Removes all items from memory. template void simpleList::clear() { if (listSize > 0 && head != nullptr && tail != nullptr) { currentPtr = head; while (listSize > 0) { remove(); } } } // Give the current size of the list. template unsigned long simpleList::size() { return listSize; } // Return the current pointer. template node *simpleList::current() { return currentPtr; }
  • 31.
    simpleList.hpp #ifndef simpleList_hpp #define simpleList_hpp #include"node.hpp" namespace std { using namespace std; template class simpleList { private: node *head; node *tail; node *currentPtr; unsigned long listSize; public: simpleList(); ~simpleList(); void append(dataType newData); void insert(dataType newData); void forward(unsigned long distance); void backwward(unsigned long distance); void toHead(); void toTail(); node *find(dataType searchData); void remove(); void clear(); unsigned long size(); node *current(); }; } #endif /* simpleList_hpp */ node.cpp #include "node.hpp" using namespace std;
  • 32.
    template node::node() { prevPtr =nullptr; nextPtr = nullptr; } template node::node(node *prv, node *nxt) { prevPtr = prv; nextPtr = nxt; } template node *node::prev() { return prevPtr; } template node *node::next() { return nextPtr; } /* Returns the data contents of the node. */ template dataType node::data() { return container; } /* Stores new data in the node, replacing the old data. */ template void node::data(dataType newData) { container = newData; } node.hpp #ifndef node_hpp #define node_hpp
  • 33.
    namespace std { template classnode { template friend class simpleList; private: node *prevPtr; node *nextPtr; dataType container; public: node(); // Create a new, blank, node. node(node *prv, node *nxt); // Create a new node with pointers. ~node(); // Destroy the node. node *next(); // Returns the next object pointer node *prev(); // Returns the previous object pointer dataType data(); // Returns the nodes data. void data(dataType); // Stores data in the node. }; } #endif /* node_hpp */ data.txt The first line The second line And another line One more line what do you try to type here? I like sugar cookies This line is boring...... This is the last line