Question
Why is this program printing an infinite loop instead of the linked list? #include #include #include #include LinkedList.h #include AddressBook.h #include Address.h using namespace std;
Why is this program printing an infinite loop instead of the linked list?
#include
#include
#include
#include "LinkedList.h"
#include "AddressBook.h"
#include "Address.h"
using namespace std;
void mainMenu(AddressBook& addresses);
void enterName(AddressBook& addresses);
void remove(AddressBook& addresses);
void changeName(AddressBook& addresses);
void generateBirthdayCards(AddressBook& addresses);
void generateAnniversaryCards(AddressBook& addresses);
void resetInput();
int main()
{
// Load the address book
AddressBook addresses;
addresses.load();
// Start the mainMenu loop
mainMenu(addresses);
return 0;
}
void mainMenu(AddressBook& addresses)
{
// Display main menu
cout << "------------------Main menu------------------" << endl;
cout << "[1]: Enter a new name into the address book" << endl;
cout << "[2]: Delete a name from the address book" << endl;
cout << "[3]: Change a name or date in the address book" << endl;
cout << "[4]: Generate birthday cards" << endl;
cout << "[5]: Generate anniversary cards" << endl;
cout << "[6]: Save and exit the card program" << endl;
cout << "[7]: Print address book." << endl;
// Prompt for user input.
cout << "Enter selection: ";
// Cleanup to make sure cin is working before gathering user input
resetInput();
int code;
cin >> code;
cout << endl;
// If their input failed, as they entered a word instead of a number
while (cin.fail())
{
// Cleanup to make sure cin is working before gathering user input
resetInput();
// Prompts that input failed, trys to recollect input
cout << "Input failed. Enter code here: ";
cin >> code;
cout << endl;
}
// Start the corresponding function the code that was entered.
switch (code)
{
case 1:
cout << "-----------------Enter Name------------------" << endl;
enterName(addresses);
break;
case 2:
cout << "-----------------Delete Name-----------------" << endl;
remove(addresses);
break;
case 3:
cout << "-----------------Change Name-----------------" << endl;
changeName(addresses);
break;
case 4:
cout << "---------------Birthday Cards----------------" << endl;
generateBirthdayCards(addresses);
break;
case 5:
cout << "-------------Anniversary Cards---------------" << endl;
generateAnniversaryCards(addresses);
break;
// Saves and exits the program
case 6:
cout << "Now closing..." << endl;
addresses.save();// Saves the addresses to the text file
exit(0);// Exits the program
break;
case 7:
cout << "----------------Address List-----------------" << endl;
addresses.print();
break;
default:
// The default operation will print wrong number.
cerr << "Sorry, wrong number." << endl;
break;
};
mainMenu(addresses);
}
void enterName(AddressBook& addresses)
{
// Cleanup to make sure cin is working before gathering user input
resetInput();
// Fill out form, for name, address, anniversary date, and birthday
Address cur;
cout << "Enter name: ";
getline(cin, cur.name);
cout << "Enter Address: ";
getline(cin, cur.streetAddress);
cout << "Enter Anniversary Date: ";
getline(cin, cur.anniversaryDate);
cout << "Enter Birthday Date: ";
getline(cin, cur.birthdayDate);
cout << endl;
// We then add the newly created address to the address book
addresses.add(cur);
}
void remove(AddressBook& addresses)
{
// Cleanup to make sure cin is working before gathering user input
resetInput();
// Get name to delete
string name;
cout << "Enter name to delete: ";
getline(cin, name);
//cout << endl;
// Remove it from the address book
addresses.remove(name);
}
void changeName(AddressBook& addresses)
{
// Cleanup to make sure cin is working before gathering user input
resetInput();
// Get name to rename
string name;
cout << "Enter name to rename: ";
cin >> name;
// Get the address with the specific name
Address addressToBeDeleted = addresses.get(name);
// If the address is NULL, the entered name doesn't exist. Exit the function.
if (addressToBeDeleted.name == "NULL")
{
cerr << "Entered name does not exist!" << endl;
return;
}
// New Address that is being formed
Address* changeAddress = new Address;
//changeAddress->streetAddress = addressToBeDeleted.streetAddress;
//changeAddress->anniversaryDate = addressToBeDeleted.anniversaryDate;
//changeAddress->birthdayDate = addressToBeDeleted.birthdayDate;
// Remove the old address
addresses.remove(name);
// Get the new name
cout << "Enter new name: ";
getline(cin, name);
cout << endl;
changeAddress->name = name;
// Add the new address to the address book
addresses.add(*changeAddress);
}
void generateBirthdayCards(AddressBook& addresses)
{
// Cleanup to make sure cin is working before gathering user input
resetInput();
// Get date
string date;
cout << "Enter date: ";
cin >> date;
// Generate birthday cards for the date
addresses.generateBirthdayCards(date);
}
void generateAnniversaryCards(AddressBook& addresses)
{
// Cleanup to make sure cin is working before gathering user input
resetInput();
// Get date
string date;
cout << "Enter date: ";
cin >> date;
// Generate anniversary cards for the date
addresses.generateAnniversaryCards(date);
}
// Cleanup to make sure cin is working before gathering user input
void resetInput()
{
// If it's failed, ignore the whole line
if (cin.fail())
{
// Removes any information user entered.
cin.clear();
//cin.ignore(std::numeric_limits::max(), ' ');
}
// If the next character is a newline, ignore it.
if (cin.peek() == ' ')
{
cin.ignore();
}
}
#include "AddressBook.h"
#include "LinkedList.h"
#include
#include
#include
#include
AddressBook::AddressBook()
{
//ctor
}
AddressBook::~AddressBook()
{
//dtor
}
// Print all of the elements in the address book
void AddressBook::print()
{
Node *it = head;
while (it != NULL)
{
std::cout << it->val;
printf("%");
it = it->next;
}
}
// Removes the passed in name
void AddressBook::remove(std::string name)
{
// Start the iterator at the head
Node *it = head;
Node *prev = NULL;
// While our iterator isnt null
//while (it != NULL)
{
// Get the current name out of the node
std::string curName = ((Address)it->val).name;
// If the current name and nameToBeDeleted are the same
if (curName == name)
{
// If w are at the head, set it's next node to the iterators next value
if (prev == NULL)
{
head = it->next;
delete it;
}
// Else set the previous values next value to the iterators next value
else
{
prev->next = it->next;
delete it;
}
// Decrease the length on removal
length--;
}
// Set the previous node to be the iterator
prev = it;
// Set the iterator to the next value
it = it->next;
}
}
// Returns the address at the name passed in, or an address whose name is NULL if the name isn't in the address book
Address AddressBook::get(std::string name)
{
// Set the iterator to the head of the linked list
Node *it = head;
// While our name isn't found, and we haven't gone through the whole list
while (it != NULL)
{
// Extract the iterators name
std::string curName = ((Address)it->val).name;
// If the iterators name is equal to the wanted name, then the value is found and returned
if (curName == name)
{
return it->val;
}
it = it->next;
}
// If the address wasn't found, return the address with the name of NULL
Address nullAdd;
nullAdd.name = "NULL";
return nullAdd;
}
// Go through every address, print out birthday cards with the same date as string passed in
void AddressBook::generateBirthdayCards(std::string date)
{
// Go through every address
Node *it = head;
while (it != NULL)
{
// If it's birthday is equal to the date passed in, print it's birthday card
Address curAddress = ((Address)it->val);
if (date == curAddress.birthdayDate)
{
printBirthdayCard(curAddress);
}
it = it->next;
}
}
void AddressBook::printBirthdayCard(Address curAddress)
{
std::cout << "-------------------------------------" << std::endl;
std::cout << "Dear " << curAddress.name << "," << std::endl << std::endl;
std::cout << "Hope your birthday is really wonderful and this coming year is the best yet!" << std::endl;
std::cout << "Love," << std::endl << std::endl;
std::cout << "Dillon" << std::endl;
}
// Go through every address, print out anniversary cards with the same date as string passed in
void AddressBook::generateAnniversaryCards(std::string date)
{
// Go through every address
Node *it = head;
while (it != NULL)
{
// If it's anniversary is equal to the date passed in, print it's birthday card
Address curAddress = ((Address)it->val);
if (date == curAddress.anniversaryDate)
{
printAnniversaryCard(curAddress);
}
it = it->next;
}
}
// Add an address to the book, make sure it is sorted alphabetically
void AddressBook::add(Address newAddress)
{
// Create a new node with our address
Node *newNode = new Node;
newNode->val = newAddress;
newNode->next = NULL;
// IF the head is null, the head and tail are both the new node
if (head == NULL)
{
head = tail = newNode;
}
else
{
// Create an iterator, and previous iterator
Node *prev = NULL;
Node *it = head;
// Go through each element
while (it != NULL)
{
// If the current name is greater than the new name,
std::string curName = ((Address)it->val).name;
if (curName > newAddress.name)
{
// Add the new node at the last location, then rewire the list
if (prev == NULL)
{
head = newNode;
newNode->next = it;
}
else
{
prev->next = newNode;
newNode->next = it;
}
return;
}
else
{
// Else we go to the next node
if (it->next == NULL)
{
it->next = newNode;
it = newNode->next;
}
else
{
prev = it;
it = it->next;
}
}
}
}
// Increment the length when an item is added
length++;
}
void AddressBook::printAnniversaryCard(Address curAddress)
{
std::cout << "-------------------------------------" << std::endl;
std::cout << "Dear " << curAddress.name << "," << std::endl << std::endl;
std::cout << "Hope your anniversary is really wonderful and this coming year is the best yet!" << std::endl;
std::cout << "Love," << std::endl << std::endl;
std::cout << "Dillon" << std::endl;
}
// Loads the address book from a properties file
void AddressBook::load()
{
// Attempt to open the address file
std::ifstream in;
in.open("addresses.properties");
// If the file didn't open, print an error message
if (!in.good())
{
std::cerr << "Cannot open addresses.properties" << std::endl;
return;
}
// While we can read without an error, keep adding addresses to our book
while (in.good())
{
// Create new address, get all 4 elements
Address* curAddress = new Address;
std::string temp;
getline(in, temp);
curAddress->name = temp;
getline(in, temp);
curAddress->streetAddress = temp;
getline(in, temp);
curAddress->anniversaryDate = temp;
getline(in, temp);
curAddress->birthdayDate = temp;
// If our input is still good after adding those 4 elements, add the new address.
if (in.good())
{
add(*curAddress);
}
}
// Close the file stream
in.close();
}
// Save the address book
void AddressBook::save()
{
// Open the properties file for our address book
std::ofstream out;
out.open("addresses.properties");
// If it failed to open, print an error and end.
if (!out.good())
{
std::cerr << "Cannot open addresses.properties" << std::endl;
return;
}
// For every address
Node* it = head;
while (it != NULL)
{
// Print it's information to a new line of the text file
Address curAddress = (Address)it->val;
out << curAddress.name << std::endl;
out << curAddress.streetAddress << std::endl;
out << curAddress.anniversaryDate << std::endl;
out << curAddress.birthdayDate << std::endl;
// Go to the next node
it = it->next;
}
// Close the outstream
out.close();
};
#pragma once
#include
#include
template
class LinkedList
{
public:
LinkedList();
~LinkedList();
int getLength();
void print();
void add(Type value);
void remove(Type value);
int length;
struct Node
{
Type val;
Node* next;
};
Node* head, *tail;
};
/**
* Sets head and tail to null, sets length to be empty.
*/
template
LinkedList::LinkedList()
{
head = NULL;
tail = NULL;
length = 0;
}
/**
* Destructor for the Linked List.
*/
template
LinkedList::~LinkedList()
{
Node* prev = NULL;
Node* it = head;
while (it != NULL)
{
prev = it;
it = it->next;
delete prev;
}
}
/**
* Prints the whole linked list.
*/
template
void LinkedList::print()
{
int index = 0;
Node* it = head;
while (it != NULL)
{
std::cout << "{" << index << ":" << it->val << "}";
if (next != NULL)
{
std::cout << ", ";
}
it = it->next;
}
}
/**
* @return the number of nodes in the linked list.
*/
template
int LinkedList::getLength()
{
return length;
}
template
void LinkedList::add(Type value)
{
Node* newNode = new Node;
newNode->val = value;
newNode->next = NULL;
if (head == NULL)
{
head = tail = newNode;
}
else
{
tail->next = newNode;
tail = newNode;
}
length++;
}
/**
* Removes all nodes that have the value passed in.
* @param value The value you want to remove.
*/
template
void LinkedList::remove(Type value)
{
Node* it = head;
Node* prev = NULL;
//while (it->next != NULL)
{
if (it->val == value)
{
if (prev == NULL)
{
head = it->next;
delete it;
}
else
{
prev->next = it->next;
delete it;
}
}
prev = it;
it = it->next;
}
length--;
}
AddressBook.h
#pragma once
#include "LinkedList.h"
#include "Address.h"
class AddressBook : public LinkedList
{
public:
AddressBook();
~AddressBook();
void print();// Print the Address Book
void add(Address curAddress);// Add an address
void remove(std::string name);// Remove an address associated with the name passed in
Address get(std::string name);// Get an address by passing in the name of that address
void generateBirthdayCards(std::string date);// Generate bday cards
void generateAnniversaryCards(std::string date);// Generate anniversary cards
void load();// Load the address book
void save();// Save the address book
private:
void printBirthdayCard(Address currAdress);
void printAnniversaryCard(Address currAdress);
};
Address.h
#pragma once
#include
#include "LinkedList.h"
class Address
{
public:
// Create an Address using these 4 params
Address(std::string name = "Not Entered",
std::string streetAddress = "Not Entered",
std::string anniversaryDate = "XX-XX-XXXX",
std::string birthdayDate = "XX-XX-XXXX");
~Address();
// Let other files print out addresses
friend std::ostream& operator<<(std::ostream& os, const Address& curAddress);
std::string name;
std::string streetAddress;
std::string anniversaryDate;
std::string birthdayDate;
};
Step by Step Solution
There are 3 Steps involved in it
Step: 1
Get Instant Access to Expert-Tailored Solutions
See step-by-step solutions with expert insights and AI powered tools for academic success
Step: 2
Step: 3
Ace Your Homework with AI
Get the answers you need in no time with our AI-driven, step-by-step assistance
Get Started