Issues With Displaying Queue Contents - c++

First off I will explain the classes and their purposes: ClinicQueue(Queue class, designed to create queues of patients), ClinicNode(typical node class, necessary for Queue), ClinicPatient(stores data about the patients in the queues), and ClinicDriver(used to construct the main application). What I need to do is to display the queue's contents - each node has a data member "info" which is an instance of ClinicPatient and contains a patient's data. In my current code I can only get one patient to print and I know there's is something wrong with my logic, but after 3 hours of the same issue and various attempts at working around it I just can't see what that problem is. How can I fix my code, or write new code to perform the necessary task? Below is the display function as well as the function intended to grab information about patients.
ClinicPatient ClinicQueue::getInfo(int pos) //get information on patients
{
ClinicNode* Current = front;
for(int i = 0; i < pos; i++)//for pos +/- 1 only outputs
//"patient 1: "(a cout in driver)
{
Current = Current -> next;
}
return Current -> info; //blows up
}
And the display function:
void ClinicDriver::Peekaboo() //breaks with more than one patient, skips last patient
{
bool cont = true;
int QueueChoice;
while (cont == true)
{
string temp;
cout << "Select a Doctor by number." << endl;
cin >> QueueChoice;
if (status[QueueChoice - 1] == true)
{
cout << "Queue is open." << endl;
string OutputS = "";
for (int a = 1; a <= Clinic[QueueChoice - 1].getSize(); a++)
{
cout << "Patient " << a << " : " << endl; //new, debugging
OutputS += Clinic[QueueChoice - 1].getInfo(a-1).tostring();//breaks here, works on 1 patient
OutputS += "\n";
}
cout << OutputS << endl;
}
else
{
cout << "Queue is empty." << endl;
}
cout << "Do you wish to continue?" << endl;
cin >> temp;
if (temp == "Yes" || temp == "yes")
{
cont = true;
}
else
{
cont = false;
}
}
}
Any and all help is greatly appreciated.

Related

The receipt have to display the fruit that user chose

#include <iostream>
#include <string>
#include <sstream>
using namespace std;
string getItemName(int k) {
if(k == 0) {
return "Sunkist Orange";
} else if(k == 1) {
return "Strawberry";
} else if(k == 2) {
return "papaya";
} else if(k == 3) {
return "Star Fruit";
} else if(k == 4) {
return "Kiwi";
}
return "";
}
int main() {
double prices[] = {2.00, 22.00, 5.00, 6.00, 10.00};
double total = 0.0;
string cart[50];
int key = 0;
int weight = 0;
int index = 0;
cout << "Welcome to Only Fresh Fruit Shop\n\nToday's fresh fruit <Price per Kg>\n";
cout << "0-Sunkist Orange RM2\n";
cout << "1-Strawberry RM22\n";
cout << "2-Papaya RM5\n";
cout << "3-Star Fruit RM6\n";
cout << "4-Kiwi RM10\n";
while (key != -1) {
double current = 0.0;
cout << "Enter fruit code <-1 to stop>: " << endl;
cin >> key;
if (key == -1) {
break;
}
cout << getItemName(key) << endl;
cout << "Enter weight <kg> : " << endl;
cin >> weight;
current = prices[key] + weight;
total = total + current;
}
cout << "-------------------------------------------------------\nReciept\n";
for(int i = 0; i < index; i++) {
cout << cart[i] << "\n";
}
cout << "TOTAL = RM" << total << endl;
return 0;
}
This is my code so far. The system have to display what fruit the user have chosen at in the receipt. My code is not working on the receipt part. Is there any other way on how to improvise the code to make it simpler? How can I improvise?
At very first you can re-organise your data better:
struct Product
{
std::string name;
double price;
};
This struct keeps the data closely related to a single product (fruit in this case) together locally.
You might organise these in an array (preferrably std::array, alternatively raw) making access to simpler – making your getItemName function obsolete entirely. Instead of a static array a std::vector would allow to manage your products dynamically (adding new ones, removing obsolete ones, ...).
You can even use this array to output your data (and here note that your condition in the while loop is redundant; if the inner check catches, the outer one cannot any more as you break before; if the inner one doesn't, the outer one won't either, so prefer a – seeming – endless loop):
std::vector<Product> products({ {"Apple", 2.0 }, { "Orange", 3.0 } });
for(;;)
{
std::cout << "Welcome ... \n";
for(auto i = products.begin(); i != products.end(); ++i)
{
std::cout << i - products.begin() << " - " << i->name
<< " RM " << i-> price << '\n';
}
// getting key, exiting on -1
if(0 <= key && key < products.size()
{
// only now get weight!
}
else
{
std::cout << "error: invalid product number" << std::endl;
}
}
Now for your cart you might just add indices into the vector or pointers to products – note, though, that these will invalidate if you modify the vector in the mean-time – if you do so you need to consider ways to correctly update the cart as well – alternatively you might just empty it. Inconvenient for the user, but easy to implement…
In any case, such a vector of pointers to products would easily allow to add arbitrary number of elements, not only 50 (at least as much as your hardware's memory can hold...) and would allow for simple deletion as well.
Calculating the full price then might occur only after the user has completed the cart:
// a map allows to hold the weights at the same time...
std::map<Product*, weight> cart;
for(;;)
{
// ...
if(0 <= key && key < products.size()
{
double weight;
std::cin >> weight;
// TODO: check for negative input!
// (always count with the dumbness of the user...)
cart[&products[key]] += weight;
// note: map's operator[] adds a new entry automatically,
// if not existing
}
}
Finally you might iterate over the cart, printing some information and calculating total price for the shopping cart:
double total = 0.0;
for(auto& entry : cart) // value type of a map always is a std::pair
{
std::cout << entry.first->name << "..." << entry.second << " kg\n";
total += entry.first->price * entry.second;
// note: you need MULTIPLICATION here, not
// addition as in your code!
}
std::cout << "Total price: RM " << total << std::endl;
This should do it whilst staying close to original code, I also improved you're method of gathering price/name a bit, try to catch the out of index exceptions or check if current index is NULL. Good luck!
#include <iostream>
#include <string>
#include <sstream>
#include <vector>;
using namespace std;
std::vector<std::string> itemList = {"Sunkist Orange", "Strawberry", "Papaya", "Star Fruit", "Kiwi"};
//If you dont want this to be global put it in the getItemName function
string getItemName(int k) {
return itemList.at(k);
}
int main() {
std::vector<double> prices = { 2.00, 22.00, 5.00, 6.00, 10.00 };
double total = 0.0;
int key = 0, weight = 0;
cout << "Welcome to Only Fresh Fruit Shop\n\nToday's fresh fruit <Price per Kg>\n";
cout << "0-Sunkist Orange RM2\n";
cout << "1-Strawberry RM22\n";
cout << "2-Papaya RM5\n";
cout << "3-Star Fruit RM6\n";
cout << "4-Kiwi RM10\n";
while (key != -1) {
double current = 0.0;
cout << "Enter fruit code <-1 to stop>: " << endl;
cin >> key;
if (key == -1) {
break;
}
cout << getItemName(key) << endl;
cout << "Enter weight <kg> : " << endl;
cin >> weight;
current += prices.at(key) + weight;
total += total + current;
cout << "-------------------------------------------------------\nReciept\n";
cout << "Purchased: " << getItemName(key) <<" "<< "TOTAL = RM" << total << "\n" << endl;
}
return 0;
}
I noticed there is a string cart[50] and int index = 0which you did not use throuoght the whole code except printing it at the end of the code. I am guessing that you want to add the fruit into the cart but it seems like you have not done so.
double price[50];
while (key != -1) {
double current = 0.0;
cout << "Enter fruit code (<-1> to stop): ";
cin >> key;
if (key == -1) break;
cout << getItemName(key) << endl;
cout << "Enter weight <kg> : ";
cin >> weight;
cart[index] = getItemName(key);
price[index] = prices[key] * weight;
total += price[index];
index++;
}
for (int i = 0; i < index; i++) {
cout << cart[i] << " " << price[i] << endl;
}
I have added some code so that cart[index] = getItemName(key). When you print each element of cart, it will now work. Also, current = prices[key] * weight is the correct one, not addition (unless your rules are different).
on a side note are you malaysian

Linked List and inserting a string in alphabetical order

I'm writing a program that allows a user to insert, delete, search, and print books. The books must print out in alphabetical order. When I'm inserting books, it works just fine but it does not put them in the right order and it will crash. Here is my code for the insert function.
void BookList::Insert(Book* nBook)
{
string name;
int quant;
double p;
cout << "Enter the title of the book." << endl;
cin.ignore();
getline(cin, name);
cout << "Enter the number of quanities of this book." << endl;
cin >> quant;
cout << "Enter the price of this book." << endl;
cin.ignore();
cin >> p;
nBook->title = name;
nBook->quantity = quant;
nBook->price = p;
nBook->next = nullptr;
//cout << "test" << endl;
//If the current book is lexicographically smallest.
if (first == nullptr) {
first = nBook;
cout << first->title << endl;
}
else if (nBook->title <= first->title)
{
cout << "new first" << endl;
nBook->next = first;
first = nBook;
}
else
{
cout << first->title << endl;
//if current book is lexicographically small between two books.
Book* prevPtr = first;
while (prevPtr != nullptr)
{
cout << "Looking at: " << prevPtr->title << endl;
if (prevPtr->title > nBook->title)
{
break;
}
else
{
prevPtr = prevPtr->next;
}
}
nBook->next = prevPtr->next;
prevPtr->next = nBook;
}
}
P.S. This is in C++
Thank you
Just because something doesn't show an error at compile doesn't mean it works fine.
Why are you using cin.ignore() with no parameters? What is the single character you are trying to ignore? You realize cin >> (someint or somedouble) already ignores whitespace and return characters, right?
More of your code is needed for context, but it seems like you're trying to fill the information for the new book into a "nBook" node before you actually initialize a new "nBook" node.
Also, I suggest not putting that output at the end in the method. If your method is for adding a new book to your linklist, just use it to add it. Put those outputs in a separate method, or in the calling method. (or maybe you just put those in for debugging purposes, in which case nvm)
Just my 0.02

Error in my c++ code using linkedlist "Stop working" [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 7 years ago.
Improve this question
my code stop working in that test case, i think that the error in function Checktables but i'm not sure and i can't fix the error please help me to tun this code correctly.
image of a test case and the error
this is a cpp file with main .cpp
#include"Header.h"
string Name;
string namess;
customer::customer()
{
name = "";
gsize = status = 0;
next = NULL;
}
customer::customer(string name1, int gsize1, int status1)
{
name = name1;
gsize = gsize1;
status = status1;
next = NULL;
}
waitinglist::waitinglist()
{
chairnum =50 ;
totalcustomers = tables = 0;
head = tail = NULL;
}
waitinglist::waitinglist(int val)
{
chairnum = 50;
totalcustomers = 0;
tables = 0;
head = tail = NULL;
}
void waitinglist::change()
{
customer*temp ;
temp = head;
cout << "enter the name: ";
cin >> namess;
while (temp != NULL)
{
if (namess == temp->name)
{
if (temp->status==2)
{
temp->status=1;
cout << "done! " << endl ;
break ;
}
}
else if (namess != temp->name)
{
temp = temp->next;
}
}
if (temp == NULL)
{
cout << "can't found! " << endl;
}
}
void waitinglist::newcustomer()
{
customer*tmp = new customer;
cout << "enter the name: "; cin >> tmp->name;
customer*tmpo=new customer;
tmpo=head ;
while (tmpo != NULL)
{
if (tmp->name != tmpo->name)
{
tmpo = tmpo->next;
}
else if (tmp->name == tmpo->name)
{
cout<<"The Name already exist! " << endl ;
cout << "enter the name: "; cin >> tmp->name;
tmpo=head;
}
}
cout << "enter the group number: "; cin >> tmp->gsize;
cout << "enter the status: "; cin >> tmp->status;
if (head == NULL) // linkedlist is empty
{
head = tail = tmp;
totalcustomers++;
}
else
{
tail->next = tmp;
tail=tail->next;
totalcustomers++;
}
}
void waitinglist::checktables()
{
float c=5.00;
customer*temp=head;
customer*found;
cout<<"enter number of tables: ";
cin >> tables ;
while (tables>=1 && temp!=NULL)
{
int x;
float y;
y=((temp->gsize)/c);
x=(temp->gsize)/c;
if (tables<y)
{
temp=temp->next;
}
else if (tables>=y)
{
if (x==y)
{
tables=tables-x ; // Correct Table!
cout<<temp->name<<endl;
}
else if (x!=y)
{
tables=tables-(x+1);
cout<<temp->name<<endl;
}
found=temp ;
delete found; // Discard
break ;
}
}
}
void waitinglist::displayall()
{
customer *tmp;
tmp = head;
if (tmp == NULL)
{
cout << "Empty!";
}
while (tmp != NULL)
{
cout << "Name: " << tmp->name <<endl;
cout << "group number: " << tmp->gsize << endl;
tmp = tmp->next;
}
cout << endl;
}
void waitinglist::diplaycustomer()
{
customer*tmp;
tmp = head;
cout << "enter the name: ";
cin >> Name;
while (tmp != NULL)
{
if (Name == tmp->name)
{
cout << "the name : " << tmp->name << endl;
cout << "the group size = " << tmp->gsize << endl;
cout << "the status = " << tmp->status << endl;
break;
}
else if (Name != tmp->name)
{
tmp = tmp->next;
}
}
if (tmp == NULL)
{
cout << "can't found!" << endl;
}
}
int main()
{
int choice;
string name1 = "";
int gsize1 = 0;
int status1 = 0;
waitinglist mylist;
cout << "Note: 1 in status means the customer not here and 2 means the customer is here.\n";
cout << "Select your option.\n\n";
cout << "(1) Add a new Customer.\n";
cout << "(2) Display information based on Name.\n";
cout << "(3) List all Names.\n";
cout << "(4) to change the status. \n" ;
cout << "(5) Check tables by name. \n";
cout << "(6) quit. \n";
do
{
cout << "\n";
cout << "Enter your choice: --> ";
cin >> choice;
if (1 <= choice && choice <= 5)
{
switch (choice)
{
case 1:
mylist.newcustomer();
break;
case 2:
mylist.diplaycustomer();
break;
case 3:
mylist.displayall();
break;
case 4:
mylist.change() ;
break;
case 5 :
mylist.checktables();
break;
default:
cout << "Invalid choice. Enter again.\n\n";
break;
}
}
else if (choice>6)
{
cout << "Invalid choice. Enter again.\n\n";
break;
}
} while (choice != 6);
return 0;
}
and this is the header file .h
#include<iostream>
#include<string>
using namespace std;
class customer
{
public:
string name;
int gsize;
int status;
customer* next;
customer();
customer(string,int,int);
};
class waitinglist
{
public:
int tables; //number of occupied tables
int chairnum;
int totalcustomers;
customer*head,*tail;
waitinglist();
waitinglist(int);
void newcustomer();
void diplaycustomer();
void displayall();
void change () ;
void checktables();
};
One error is that your checktables function corrupts your linked list structure by calling delete on one of the nodes:
found = temp;
delete found; // Discard
What you've just done in those lines above is to have a linked list with a broken (invalid) link in it. Any functions that now traverses the list (like displaytables) will now hit the broken link, and things start to go haywire.
To delete a node from a linked list, you have to not just call delete, but adjust the link in waitinglist that used to point to that deleted node and have it point to the next node after the deleted one.
Think of it like a real chain -- if one of the links in the chain needs to be removed, you have to physically remove it, and hook the link before it to the next good link. You didn't do this step.
I won't write the code for that, but this is what you should have seen much earlier in the development of your program. Better yet would have been to write a singly-linked list class that adds and removes nodes correctly first. Test it, and then once it can add and remove nodes successfully without error, then use it in your larger program.

"Return" not working, cannot "exit" a function [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
I have some functions that need to be called multiple times, as such
int i;
i = 10;
while (i > 0)
{
selectletter(wordArray);
computerTurn(wordArray);
printGrid(grid);
i--;
}
The function selectletter works fine, and near the end of that function, it calls another function, "claimword". Claimword runs entirely fine, but at the end of the function, the program crashes when it runs out of context, as opposed to it just moving on to computerTurn as it should as shown above. I looked up on SO how to "exit" a function, and everyone said that "return;" would work fine, even in a void function. However, when I try using return, nothing at all happens, except for anything after the return statement is ignored. Can anyone tell me why the return statement doesn't work?
void claimword(Tile grid[7][6], char letter, string wordArray[100])
{
cout << "Would you like to claim a word? (Y/N)" << endl;
char chooseinput;
cin >> chooseinput;
if ((chooseinput == 'y') || (chooseinput == 'Y'))
{
printGrid(grid);
cout << "Please enter the word you would like to claim." << endl;
string input;
cin >> input;
int inthegrid = 0;
int errormessage = 0;
compchecker(grid, input, inthegrid);
int length;
if (inthegrid = 1)
{
for(int i = 0; i < 100; ++i)
{
if (input == wordArray[i])
{
if (input.find(letter) != std::string::npos)
{
string strl;
strl = wordArray[i];
length = strl.length();
cout << "You have claimed the word " << strl << endl;
wordArray[i] = "/";
}
else
{
errormessage = 1;
}
}
else
{
///cout << "Sorry, that word is not in the dictionary." << endl;
errormessage = 2;
}
}
if (errormessage = 1)
{
cout << "Sorry you cannot claim that word." << endl;
}
if (errormessage = 2)
{
cout << "Sorry, that word is not in the dictionary." << endl;
}
if (length == 3)
{
human.humanpoints = human.humanpoints + 1;
wordsthisturn = wordsthisturn + 1;
cout << "You have earned one point!" << endl;
}
if (length == 4)
{
human.humanpoints = human.humanpoints + 2;
wordsthisturn = wordsthisturn + 2;
cout << "You have earned two points!" << endl;
}
if (length == 5)
{
human.humanpoints = human.humanpoints + 4;
wordsthisturn = wordsthisturn + 4;
cout << "You have earned four points!" << endl;
}
if (length == 6)
{
human.humanpoints = human.humanpoints + 8;
wordsthisturn = wordsthisturn + 8;
cout << "You have earned eight points!" << endl;
}
if (length == 7)
{
human.humanpoints = human.humanpoints + 16;
wordsthisturn = wordsthisturn + 16;
cout << "You have earned sixteen points!" << endl;
}
else
{
cout << "Your word was too small to claim any points." << endl;
}
}
}
else
{
cout << "End of Player Turn." << endl;
//return;
}
cout <<"Test1";
return;
cout <<"Test2";
}
Regardless of the input I give it (y/n and such), "Test1" displays, but "Test2" doesn't. My theory is that the program doesn't return all the way, or I'm just simply not using it right.
EDIT:
With an edited statement in the main function,
selectletter(wordArray);
cout << "test11";
computerTurn(wordArray);
What should happen is that the selectletter function should be called. The selectletter function, at the end of it, calls another function, claimWord. claimWord is posted above. At the end of the function, it should end. There should be nothing left for it to do, and after all those if/elses regarding points, and even if no points are scored, or anything in the function happens, the function should end. The program should then display "test11", but it does not.
EDIT2:
void selectletter(string wordArray[100])
{
cout << endl;
cout << "REMAINING LETTERS:" << endl;
cout << human.humanletters << endl;
cout << "Select a letter.";
int length;
length = human.humanletters.size();
char input;
cin >> input;
int column;
int row = 7;
int cinput;
//mght have to change since 0 is the first val
cout << "What column would you like to drop that in? (1-7)";
cin >> cinput;
column = cinput - 1;
//cout << "Test1";
while (row > 0)
{
if (grid[row-1][column].active == true)
{
row--;
//cout << "Test3";
}
else
for(int i = 0; i < length; i++)
{
if(human.humanletters[i] == input)
{
//cout << "Test5";
human.humanletters.erase(std::remove(human.humanletters.begin(), human.humanletters.end(), input), human.humanletters.end());
grid[row-1][column].letter = input;
grid[row-1][column].active = true;
cout << endl;
//cout << "Test6";
claimword(grid, input, wordArray);
//this removes ALL instances of the letter, however
}
break;
//need to add something for if the letter is not in the string
//}
//row = 9999;
}
}
}
Regardless of the input I give it (y/n and such), "Test1" displays, but "Test2" doesn't.
That is what it is supposed to do. You called return after displaying Test1 and before displaying Test2, so the latter was skipped. return is an immediate return to the function that called the current function.
Your while loop has the condition while (row > 0), and you only decrement row when (grid[row-1][column].active == true). If that ever evaluates to false, you won't decrement row and your program runs forever.
Perhaps your break; was meant to break out of the while loop, but all it will do is break out of the for loop. A break statement breaks out of the nearest enclosing loop/switch block.

Reading input from a text file, omits the first and adds a nonsense value to the end?

When I input locations from a txt file I am getting a peculiar error where it seems to miss off the first entry, yet add a garbage entry to the end of the link list (it is designed to take the name, latitude and longitude for each location you will notice). I imagine this to be an issue with where it starts collecting the inputs and where it stops but I cant find the error!! It reads the first line correctly but then skips to the next before adding it because during testing for the bug it had no record of the first location Lisbon though whilst stepping into the method call it was reading it. Very bizarre but hopefully someone knows the issue. Here is firstly my header file:
#include <string>
struct locationNode
{
char nodeCityName [35];
double nodeLati;
double nodeLongi;
locationNode* Next;
void CorrectCase() // Correct upper and lower case letters of input
{
int MAX_SIZE = 35;
int firstLetVal = this->nodeCityName[0], letVal;
int n = 1; // variable for name index from second letter onwards
if((this->nodeCityName[0] >90) && (this->nodeCityName[0] < 123)) // First letter is lower case
{
firstLetVal = firstLetVal - 32; // Capitalise first letter
this->nodeCityName[0] = firstLetVal;
}
while(n <= MAX_SIZE - 1)
{
if((this->nodeCityName[n] >= 65) && (this->nodeCityName[n] <= 90))
{
letVal = this->nodeCityName[n] + 32;
this->nodeCityName[n] = letVal;
}
n++;
}
//cityNameInput = this->nodeCityName;
}
};
class Locations
{
private:
int size;
public:
Locations(){
}; // constructor for the class
locationNode* Head;
//int Add(locationNode* Item);
};
And here is the file containing main:
// U08221.cpp : main project file.
#include "stdafx.h"
#include "Locations.h"
#include <iostream>
#include <string>
#include <fstream>
using namespace std;
int n = 0,x, locationCount = 0, MAX_SIZE = 35;
string cityNameInput;
char targetCity[35];
bool acceptedInput = false, userInputReq = true, match = false, nodeExists = false;// note: addLocation(), set to true to enable user input as opposed to txt file
locationNode *start_ptr = NULL; // pointer to first entry in the list
locationNode *temp, *temp2; // Part is a pointer to a new locationNode we can assign changing value followed by a call to Add
locationNode *seek, *bridge;
void setElementsNull(char cityParam[])
{
int y=0, count =0;
while(cityParam[y] != NULL)
{
y++;
}
while(y < MAX_SIZE)
{
cityParam[y] = NULL;
y++;
}
}
void addLocation()
{
temp = new locationNode; // declare the space for a pointer item and assign a temporary pointer to it
if(!userInputReq) // bool that determines whether user input is required in adding the node to the list
{
cout << endl << "Enter the name of the location: ";
cin >> temp->nodeCityName;
temp->CorrectCase();
setElementsNull(temp->nodeCityName);
cout << endl << "Please enter the latitude value for this location: ";
cin >> temp->nodeLati;
cout << endl << "Please enter the longitude value for this location: ";
cin >> temp->nodeLongi;
cout << endl;
}
temp->Next = NULL; //set to NULL as when one is added it is currently the last in the list and so can not point to the next
if(start_ptr == NULL){ // if list is currently empty, start_ptr will point to this node
start_ptr = temp;
}
else
{ temp2 = start_ptr;
// We know this is not NULL - list not empty!
while (temp2->Next != NULL)
{
temp2 = temp2->Next; // Move to next link in chain until reach end of list
}
temp2->Next = temp;
}
++locationCount; // increment counter for number of records in list
if(!userInputReq){
cout << "Location sucessfully added to the database! There are " << locationCount << " location(s) stored" << endl;
}
}
void populateList(){
ifstream inputFile;
inputFile.open ("locations.txt", ios::in);
userInputReq = true;
temp = new locationNode; // declare the space for a pointer item and assign a temporary pointer to it
do
{
inputFile.get(temp->nodeCityName, 35, ' ');
setElementsNull(temp->nodeCityName);
inputFile >> temp->nodeLati;
inputFile >> temp->nodeLongi;
setElementsNull(temp->nodeCityName);
if(temp->nodeCityName[0] == 10) //remove linefeed from input
{
for(int i = 0; temp->nodeCityName[i] != NULL; i++)
{
temp->nodeCityName[i] = temp->nodeCityName[i + 1];
}
}
addLocation();
}
while(!inputFile.eof());
userInputReq = false;
cout << "Successful!" << endl << "List contains: " << locationCount << " entries" << endl;
cout << endl;
inputFile.close();
}
bool nodeExistTest(char targetCity[]) // see if entry is present in the database
{
match = false;
seek = start_ptr;
int letters = 0, letters2 = 0, x = 0, y = 0;
while(targetCity[y] != NULL)
{
letters2++;
y++;
}
while(x <= locationCount) // locationCount is number of entries currently in list
{
y=0, letters = 0;
while(seek->nodeCityName[y] != NULL) // count letters in the current name
{
letters++;
y++;
}
if(letters == letters2) // same amount of letters in the name
{
y = 0;
while(y <= letters) // compare each letter against one another
{
if(targetCity[y] == seek->nodeCityName[y])
{
match = true;
y++;
}
else
{
match = false;
y = letters + 1; // no match, terminate comparison
}
}
}
if(match)
{
x = locationCount + 1; //found match so terminate loop
}
else{
if(seek->Next != NULL)
{
bridge = seek;
seek = seek->Next;
x++;
}
else
{
x = locationCount + 1; // end of list so terminate loop
}
}
}
return match;
}
void deleteRecord() // complete this
{
int junction = 0;
locationNode *place;
cout << "Enter the name of the city you wish to remove" << endl;
cin >> targetCity;
setElementsNull(targetCity);
if(nodeExistTest(targetCity)) //if this node does exist
{
if(seek == start_ptr) // if it is the first in the list
{
junction = 1;
}
if(seek != start_ptr && seek->Next == NULL) // if it is last in the list
{
junction = 2;
}
switch(junction) // will alter list accordingly dependant on where the searched for link is
{
case 1:
start_ptr = start_ptr->Next;
delete seek;
--locationCount;
break;
case 2:
place = seek;
seek = bridge;
delete place;
--locationCount;
break;
default:
bridge->Next = seek->Next;
delete seek;
--locationCount;
break;
}
}
else
{ cout << targetCity << "That entry does not currently exist" << endl << endl << endl;
}
}
void searchDatabase()
{
char choice;
cout << "Enter search term..." << endl;
cin >> targetCity;
if(nodeExistTest(targetCity))
{
cout << "Entry: " << endl << endl;
}
else
{
cout << "Sorry, that city is not currently present in the list." << endl << "Would you like to add this city now Y/N?" << endl;
cin >> choice;
/*while(choice != ('Y' || 'N'))
{
cout << "Please enter a valid choice..." << endl;
cin >> choice;
}*/
switch(choice)
{
case 'Y':
addLocation();
break;
case 'N':
break;
default :
cout << "Invalid choice" << endl;
break;
}
}
}
void printDatabase()
{
temp = start_ptr; // set temp to the start of the list
do
{ if (temp == NULL)
{
cout << "You have reached the end of the database" << endl;
}
else
{ // Display details for what temp points to at that stage
cout << "Location : " << temp->nodeCityName << endl;
cout << "Latitude : " << temp->nodeLati << endl;
cout << "Longitude : " << temp->nodeLongi << endl;
cout << endl;
// Move on to next locationNode if one exists
temp = temp->Next;
}
}
while (temp != NULL);
}
void nameValidation(string name)
{
n = 0; // start from first letter
x = name.size();
while(!acceptedInput)
{
if((name[n] >= 65) && (name[n] <= 122)) // is in the range of letters
{
while(n <= x - 1)
{
while((name[n] >=91) && (name[n] <=97)) // ERROR!!
{
cout << "Please enter a valid city name" << endl;
cin >> name;
}
n++;
}
}
else {
cout << "Please enter a valid city name" << endl;
cin >> name;
}
if(n <= x - 1)
{
acceptedInput = true;
}
}
cityNameInput = name;
}
int main(array<System::String ^> ^args)
{
//main contains test calls to functions at present
cout << "Populating list...";
populateList();
printDatabase();
deleteRecord();
printDatabase();
cin >> cityNameInput;
}
The text file contains this (ignore the names, they are just for testing!!):
Lisbon 45 47
Fattah 45 47
Darius 42 49
Peter 45 27
Sarah 85 97
Michelle 45 47
John 25 67
Colin 35 87
Shiron 40 57
George 34 45
Sean 22 33
The output omits Lisbon, but adds on a garbage entry with nonsense values. Any ideas why? Thank you in advance.
The main function creates a new locationNode and stores it in the global variable temp, then reads the first dataset and stores it in that node.
Then you call addLocation() which starts by creating another new locationNode which replaces the existing one in temp. This new node is then inserted into the list.
The next iteration of the main loop then fills that temp value with values and addLocation() inserts another brand new locationNode into the list. So the first dataset isn't stored in the list and each iteration ends up by inserting an uninitialized new node.
As you see using global variables can lead to confusing situations and you code would surely become clearer if you were passing the nodes as parameters to your functions.