B
B. Williams
I have written some code to accept input and place this input at the
beginning or end of a list, but I need assistance including a class so that
it will allow input of a phone number that is properly formatted. I'll post
my code below. Thanks in advance.
This is the code for the linked list. It tests using int's and string's.
#ifndef LIST_H
#define LIST_H
#include <iostream>
using std::cout;
#include "Listnode.h"
template< typename NODETYPE >
class List
{
public:
List();
~List();
void insertAtFront( const NODETYPE & );
void insertAtBack( const NODETYPE & );
bool removeFromFront( NODETYPE & );
bool removeFromBack( NODETYPE & );
bool isEmpty() const;
void print() const;
private:
ListNode< NODETYPE > *firstPtr;
ListNode< NODETYPE > *lastPtr;
// utility function to allocate new node
ListNode< NODETYPE > *getNewNode( const NODETYPE & );
}; // end class List
// default constructor
template< typename NODETYPE >
List< NODETYPE >::List()
: firstPtr( 0 ), lastPtr( 0 )
{
}
// destructor
template< typename NODETYPE >
List< NODETYPE >::~List()
{
if ( !isEmpty() ) // List is not empty
{
cout << "Destroying nodes ...\n";
ListNode< NODETYPE > *currentPtr = firstPtr;
ListNode< NODETYPE > *tempPtr;
while ( currentPtr != 0 ) // delete remaining nodes
{
tempPtr = currentPtr;
cout << tempPtr->data << '\n';
currentPtr = currentPtr->nextPtr;
delete tempPtr;
} // end while
} // end if
cout << "All nodes destroyed\n\n";
} // end List destructor
// insert node at front of list
template< typename NODETYPE >
void List< NODETYPE >::insertAtFront( const NODETYPE &value )
{
ListNode< NODETYPE > *newPtr = getNewNode( value ); // new node
if ( isEmpty() ) // List is empty
firstPtr = lastPtr = newPtr; // new list has only one node
else // List is not empty
{
newPtr->nextPtr = firstPtr; // point new node to previous 1st node
firstPtr = newPtr; // aim firstPtr at new node
} // end else
} // end function insertAtFront
// insert node at back of list
template< typename NODETYPE >
void List< NODETYPE >::insertAtBack( const NODETYPE &value )
{
ListNode< NODETYPE > *newPtr = getNewNode( value ); // new node
if ( isEmpty() ) // List is empty
firstPtr = lastPtr = newPtr; // new list has only one node
else // List is not empty
{
lastPtr->nextPtr = newPtr; // update previous last node
lastPtr = newPtr; // new last node
} // end else
} // end function insertAtBack
// delete node from front of list
template< typename NODETYPE >
bool List< NODETYPE >::removeFromFront( NODETYPE &value )
{
if ( isEmpty() ) // List is empty
return false; // delete unsuccessful
else
{
ListNode< NODETYPE > *tempPtr = firstPtr; // hold tempPtr to delete
if ( firstPtr == lastPtr )
firstPtr = lastPtr = 0; // no nodes remain after removal
else
firstPtr = firstPtr->nextPtr; // point to previous 2nd node
value = tempPtr->data; // return data being removed
delete tempPtr; // reclaim previous front node
return true; // delete successful
} // end else
} // end function removeFromFront
// delete node from back of list
template< typename NODETYPE >
bool List< NODETYPE >::removeFromBack( NODETYPE &value )
{
if ( isEmpty() ) // List is empty
return false; // delete unsuccessful
else
{
ListNode< NODETYPE > *tempPtr = lastPtr; // hold tempPtr to delete
if ( firstPtr == lastPtr ) // List has one element
firstPtr = lastPtr = 0; // no nodes remain after removal
else
{
ListNode< NODETYPE > *currentPtr = firstPtr;
// locate second-to-last element
while ( currentPtr->nextPtr != lastPtr )
currentPtr = currentPtr->nextPtr; // move to next node
lastPtr = currentPtr; // remove last node
currentPtr->nextPtr = 0; // this is now the last node
} // end else
value = tempPtr->data; // return value from old last node
delete tempPtr; // reclaim former last node
return true; // delete successful
} // end else
} // end function removeFromBack
// is List empty?
template< typename NODETYPE >
bool List< NODETYPE >::isEmpty() const
{
return firstPtr == 0;
} // end function isEmpty
// return pointer to newly allocated node
template< typename NODETYPE >
ListNode< NODETYPE > *List< NODETYPE >::getNewNode(
const NODETYPE &value )
{
return new ListNode< NODETYPE >( value );
} // end function getNewNode
// display contents of List
template< typename NODETYPE >
void List< NODETYPE >:
rint() const
{
if ( isEmpty() ) // List is empty
{
cout << "The list is empty\n\n";
return;
} // end if
ListNode< NODETYPE > *currentPtr = firstPtr;
cout << "The list is: ";
while ( currentPtr != 0 ) // get element data
{
cout << currentPtr->data << ' ';
currentPtr = currentPtr->nextPtr;
} // end while
cout << "\n\n";
} // end function print
#endif
#ifndef LISTNODE_H
#define LISTNODE_H
template< typename NODETYPE > class List;
template< typename NODETYPE >
class ListNode
{
friend class List< NODETYPE >;
public:
ListNode( const NODETYPE & );
NODETYPE getData() const;
private:
NODETYPE data;
ListNode< NODETYPE > *nextPtr; // next node in list
}; // end class ListNode
// constructor
template< typename NODETYPE >
ListNode< NODETYPE >::ListNode( const NODETYPE &info )
: data( info ), nextPtr( 0 )
{
} // end ListNode constructor
// return copy of data in node
template< typename NODETYPE >
NODETYPE ListNode< NODETYPE >::getData() const
{
return data;
} // end function getData
#endif
#include <iostream>
using std::cin;
using std::cout;
using std::endl;
#include <string>
using std::string;
#include "List.h"
// function to test a List
template< typename T >
void testList( List< T > &listObject, const string &typeName )
{
cout << "Testing a List of " << typeName << " values\n";
instructions(); // display instructions
int choice; // store user choice
T value; // store input value
do // perform user-selected actions
{
cout << "? ";
cin >> choice;
switch ( choice )
{
case 1: // insert at beginning
cout << "Enter " << typeName << ": ";
cin >> value;
listObject.insertAtFront( value );
listObject.print();
break;
case 2: // insert at end
cout << "Enter " << typeName << ": ";
cin >> value;
listObject.insertAtBack( value );
listObject.print();
break;
case 3: // remove from beginning
if ( listObject.removeFromFront( value ) )
cout << value << " removed from list\n";
listObject.print();
break;
case 4: // remove from end
if ( listObject.removeFromBack( value ) )
cout << value << " removed from list\n";
listObject.print();
break;
} // end switch
} while ( choice != 5 ); // end do...while
cout << "End list test\n\n";
} // end function testList
void instructions()
{
cout << "Enter one of the following:\n"
<< " 1 to insert at beginning of list\n"
<< " 2 to insert at end of list\n"
<< " 3 to delete from beginning of list\n"
<< " 4 to delete from end of list\n"
<< " 5 to end list processing\n";
} // end function instructions
int main()
{
// test List of int values
List< int > intList;
testList( intList, "integer" );
// test List of string values
List< string > stringList;
testList( stringList, "string" );
return 0;
} // end main
I want to be able to include my phone number class so that this will accept
phone numbers as input. Here is the phone class
#ifndef PHONENUMBER_H
#define PHONENUMBER_H
#include <iostream>
using std:
stream;
using std::istream;
#include <string>
using std::string;
#include <iomanip>
using std::setw;
class PhoneNumber
{
friend ostream &operator<<( ostream &, const PhoneNumber & );
friend istream &operator>>( istream &, PhoneNumber & );
private:
string areaCode; // 3-digit area code
string exchange; // 3-digit exchange
string line; // 4-digit line
}; // end class PhoneNumber
ostream &operator<<( ostream &output, const PhoneNumber &number )
{
output << "(" << number.areaCode << ") "
<< number.exchange << "-" << number.line;
return output; // enables cout << a << b << c;
} // end function operator<<
istream &operator>>( istream &input, PhoneNumber &number )
{
input.ignore(); // skip (
input >> setw( 3 ) >> number.areaCode; // input area code
input.ignore( 2 ); // skip ) and space
input >> setw( 3 ) >> number.exchange; // input exchange
input.ignore(); // skip dash (-)
input >> setw( 4 ) >> number.line; // input line
return input; // enables cin >> a >> b >> c;
} // end function operator>>
#endif
beginning or end of a list, but I need assistance including a class so that
it will allow input of a phone number that is properly formatted. I'll post
my code below. Thanks in advance.
This is the code for the linked list. It tests using int's and string's.
#ifndef LIST_H
#define LIST_H
#include <iostream>
using std::cout;
#include "Listnode.h"
template< typename NODETYPE >
class List
{
public:
List();
~List();
void insertAtFront( const NODETYPE & );
void insertAtBack( const NODETYPE & );
bool removeFromFront( NODETYPE & );
bool removeFromBack( NODETYPE & );
bool isEmpty() const;
void print() const;
private:
ListNode< NODETYPE > *firstPtr;
ListNode< NODETYPE > *lastPtr;
// utility function to allocate new node
ListNode< NODETYPE > *getNewNode( const NODETYPE & );
}; // end class List
// default constructor
template< typename NODETYPE >
List< NODETYPE >::List()
: firstPtr( 0 ), lastPtr( 0 )
{
}
// destructor
template< typename NODETYPE >
List< NODETYPE >::~List()
{
if ( !isEmpty() ) // List is not empty
{
cout << "Destroying nodes ...\n";
ListNode< NODETYPE > *currentPtr = firstPtr;
ListNode< NODETYPE > *tempPtr;
while ( currentPtr != 0 ) // delete remaining nodes
{
tempPtr = currentPtr;
cout << tempPtr->data << '\n';
currentPtr = currentPtr->nextPtr;
delete tempPtr;
} // end while
} // end if
cout << "All nodes destroyed\n\n";
} // end List destructor
// insert node at front of list
template< typename NODETYPE >
void List< NODETYPE >::insertAtFront( const NODETYPE &value )
{
ListNode< NODETYPE > *newPtr = getNewNode( value ); // new node
if ( isEmpty() ) // List is empty
firstPtr = lastPtr = newPtr; // new list has only one node
else // List is not empty
{
newPtr->nextPtr = firstPtr; // point new node to previous 1st node
firstPtr = newPtr; // aim firstPtr at new node
} // end else
} // end function insertAtFront
// insert node at back of list
template< typename NODETYPE >
void List< NODETYPE >::insertAtBack( const NODETYPE &value )
{
ListNode< NODETYPE > *newPtr = getNewNode( value ); // new node
if ( isEmpty() ) // List is empty
firstPtr = lastPtr = newPtr; // new list has only one node
else // List is not empty
{
lastPtr->nextPtr = newPtr; // update previous last node
lastPtr = newPtr; // new last node
} // end else
} // end function insertAtBack
// delete node from front of list
template< typename NODETYPE >
bool List< NODETYPE >::removeFromFront( NODETYPE &value )
{
if ( isEmpty() ) // List is empty
return false; // delete unsuccessful
else
{
ListNode< NODETYPE > *tempPtr = firstPtr; // hold tempPtr to delete
if ( firstPtr == lastPtr )
firstPtr = lastPtr = 0; // no nodes remain after removal
else
firstPtr = firstPtr->nextPtr; // point to previous 2nd node
value = tempPtr->data; // return data being removed
delete tempPtr; // reclaim previous front node
return true; // delete successful
} // end else
} // end function removeFromFront
// delete node from back of list
template< typename NODETYPE >
bool List< NODETYPE >::removeFromBack( NODETYPE &value )
{
if ( isEmpty() ) // List is empty
return false; // delete unsuccessful
else
{
ListNode< NODETYPE > *tempPtr = lastPtr; // hold tempPtr to delete
if ( firstPtr == lastPtr ) // List has one element
firstPtr = lastPtr = 0; // no nodes remain after removal
else
{
ListNode< NODETYPE > *currentPtr = firstPtr;
// locate second-to-last element
while ( currentPtr->nextPtr != lastPtr )
currentPtr = currentPtr->nextPtr; // move to next node
lastPtr = currentPtr; // remove last node
currentPtr->nextPtr = 0; // this is now the last node
} // end else
value = tempPtr->data; // return value from old last node
delete tempPtr; // reclaim former last node
return true; // delete successful
} // end else
} // end function removeFromBack
// is List empty?
template< typename NODETYPE >
bool List< NODETYPE >::isEmpty() const
{
return firstPtr == 0;
} // end function isEmpty
// return pointer to newly allocated node
template< typename NODETYPE >
ListNode< NODETYPE > *List< NODETYPE >::getNewNode(
const NODETYPE &value )
{
return new ListNode< NODETYPE >( value );
} // end function getNewNode
// display contents of List
template< typename NODETYPE >
void List< NODETYPE >:
{
if ( isEmpty() ) // List is empty
{
cout << "The list is empty\n\n";
return;
} // end if
ListNode< NODETYPE > *currentPtr = firstPtr;
cout << "The list is: ";
while ( currentPtr != 0 ) // get element data
{
cout << currentPtr->data << ' ';
currentPtr = currentPtr->nextPtr;
} // end while
cout << "\n\n";
} // end function print
#endif
#ifndef LISTNODE_H
#define LISTNODE_H
template< typename NODETYPE > class List;
template< typename NODETYPE >
class ListNode
{
friend class List< NODETYPE >;
public:
ListNode( const NODETYPE & );
NODETYPE getData() const;
private:
NODETYPE data;
ListNode< NODETYPE > *nextPtr; // next node in list
}; // end class ListNode
// constructor
template< typename NODETYPE >
ListNode< NODETYPE >::ListNode( const NODETYPE &info )
: data( info ), nextPtr( 0 )
{
} // end ListNode constructor
// return copy of data in node
template< typename NODETYPE >
NODETYPE ListNode< NODETYPE >::getData() const
{
return data;
} // end function getData
#endif
#include <iostream>
using std::cin;
using std::cout;
using std::endl;
#include <string>
using std::string;
#include "List.h"
// function to test a List
template< typename T >
void testList( List< T > &listObject, const string &typeName )
{
cout << "Testing a List of " << typeName << " values\n";
instructions(); // display instructions
int choice; // store user choice
T value; // store input value
do // perform user-selected actions
{
cout << "? ";
cin >> choice;
switch ( choice )
{
case 1: // insert at beginning
cout << "Enter " << typeName << ": ";
cin >> value;
listObject.insertAtFront( value );
listObject.print();
break;
case 2: // insert at end
cout << "Enter " << typeName << ": ";
cin >> value;
listObject.insertAtBack( value );
listObject.print();
break;
case 3: // remove from beginning
if ( listObject.removeFromFront( value ) )
cout << value << " removed from list\n";
listObject.print();
break;
case 4: // remove from end
if ( listObject.removeFromBack( value ) )
cout << value << " removed from list\n";
listObject.print();
break;
} // end switch
} while ( choice != 5 ); // end do...while
cout << "End list test\n\n";
} // end function testList
void instructions()
{
cout << "Enter one of the following:\n"
<< " 1 to insert at beginning of list\n"
<< " 2 to insert at end of list\n"
<< " 3 to delete from beginning of list\n"
<< " 4 to delete from end of list\n"
<< " 5 to end list processing\n";
} // end function instructions
int main()
{
// test List of int values
List< int > intList;
testList( intList, "integer" );
// test List of string values
List< string > stringList;
testList( stringList, "string" );
return 0;
} // end main
I want to be able to include my phone number class so that this will accept
phone numbers as input. Here is the phone class
#ifndef PHONENUMBER_H
#define PHONENUMBER_H
#include <iostream>
using std:
using std::istream;
#include <string>
using std::string;
#include <iomanip>
using std::setw;
class PhoneNumber
{
friend ostream &operator<<( ostream &, const PhoneNumber & );
friend istream &operator>>( istream &, PhoneNumber & );
private:
string areaCode; // 3-digit area code
string exchange; // 3-digit exchange
string line; // 4-digit line
}; // end class PhoneNumber
ostream &operator<<( ostream &output, const PhoneNumber &number )
{
output << "(" << number.areaCode << ") "
<< number.exchange << "-" << number.line;
return output; // enables cout << a << b << c;
} // end function operator<<
istream &operator>>( istream &input, PhoneNumber &number )
{
input.ignore(); // skip (
input >> setw( 3 ) >> number.areaCode; // input area code
input.ignore( 2 ); // skip ) and space
input >> setw( 3 ) >> number.exchange; // input exchange
input.ignore(); // skip dash (-)
input >> setw( 4 ) >> number.line; // input line
return input; // enables cin >> a >> b >> c;
} // end function operator>>
#endif