#include <string>
using namespace std;
class PersonList
{
private:
char aName[7];
int aBribe;
PersonList *link;
public:
void addNodes();
void display();
};
#include <iostream>
#include <string>
using namespace std;
#include "mylink.h"
void PersonList::addNodes()
{
PersonList *temp2;
PersonList* startPtr = new PersonList();
PersonList* current = new PersonList();
PersonList *temp = new PersonList();//created the first node on the list
cout<<"Enter the person's name: ";
cin>>temp->aName;
cout<<"Enter the person's contribution: ";
cin>>temp->aBribe;
temp->link=NULL;//when i get last node, link will point to null(where am i in list?)
if(startPtr==NULL)
{
startPtr = temp;
current = startPtr;
}
else
{
temp2 = startPtr;
while(temp2->link!=NULL)
temp2 = temp2->link;
temp2->link=temp;
}
//}
}
void PersonList::display()
{
PersonList *temp;
PersonList *startPtr = this;
temp=startPtr;
while(temp != NULL)
{
cout<<temp->aName<<"\t\t"<<temp->aBribe<<endl;
temp = temp->link;
}
}
#include <iostream>
#include "mylink.h"
using namespace std;
int displayMenu (void);
void processChoice(int, PersonList&);
int main()
{
int num;
PersonList myList;
do
{
num = displayMenu();
if (num != 3)
processChoice(num, myList);
} while (num != 3);
return 0;
}
int displayMenu(void)
{
int choice;
cout << "\nMenu\n";
cout << "==============================\n\n";
cout << "1. Add student to waiting list\n";
cout << "2. View waiting list\n";
cout << "3. Exit program\n\n";
cout << "Please enter choice: ";
cin >> choice;
cin.ignore();
return choice;
}
void processChoice(int choice, PersonList& p)
{
switch(choice)
{
case 1: p.addNodes();
break;
case 2: p.display();
break;
}
}
My question is the display function is not displaying name and contribution that I enter.
Im using temp variable as a pointer node to call aName and aBribe. This goes through the list while it has not reached null. Nothing shows in output
You are creating a new list:
PersonList *startPtr = new PersonList();
and then showing that. So, naturally it is empty.
You have a similar problem in your addNodes method. You are adding nodes to a new list, then throwing it away, which is actually a memory leak.
Related
Here is Main.cpp:
#include <iostream>
#include <cstdlib>
#include "linklist.h"
using namespace std;
void menu(List &);
int main()
{
//new list
List list;
menu(list);
return 0;
}
void menu(List &list)
{
char choice;
int item;
do {
system("CLS"); // for ise of std library
cout<<"\t Menu\n";
cout<<"\t\tOptions\n\n";
cout<<"\t\tInsert a Student (press I)\n";
cout<<"\t\tRemove a Student (press R)\n";
cout<<"\t\tDisplay List of Student (press D)\n";
cout<<"\t\tClear List (press C)\n";
cout<<"\t\tExit (press E)\n";
cout<<"What would you like to do ? Press the coresponding key:";
cin>>choice;
choice = toupper(choice);
cin.ignore();
switch(choice)
{
case 'I':
list.Insert();
break;
case 'R':
list.Remove();
break;
case 'D':
list.Display();cin.get();
break;
case 'C':
list.Clear();cin.get();
break;
}
Here is list.cpp
#include "linklist.h"
#include <iostream>
using namespace std;
// insert at begining of the linked list
void List::Insert()
{
int student_id;
short test_one,test_two;
float average;
cout << "Enter the Student's ID: "; cin >> student_id;
cout << "Enter the score of Test One: "; cin>> test_one;
cout << "Enter the score of Test Two: "; cin >> test_two;
average = (test_one + (double)test_two)/2;
// new node
Node* newnode = new Node();
newnode->setnode(student_id,test_one,test_two,average);
newnode->setnext(head);
head = newnode;
}
// deletes from the last node in the list
void List::Remove()
{
Node* curr = head;
if (curr = NULL) {
cout << "No nodes to remove\n ";
return;
}
else if (curr->getnext() == NULL ) // it only has 1 !
{
delete curr;
head = NULL;
}
else
{
Node *prev;
do
{
prev = curr; // the prev becomes the curr
curr = curr->getnext();
}while(curr->getnext() != NULL); // while the next one is not empty
prev->setnext(NULL);
delete curr; // delte the curr and it will repeat as prev becomes curr
// unill curr=NULL
}
}
// displays the nodes to the console
void List::Display()
{
Print(head);
}
void List::Print(Node* temp)
{
if (temp = NULL)
{
cout << "End" << endl;
return;
}else
{
temp->getnode();
Print(temp->getnext()); // these two steps will continue
} // until temp=NULL
}
// clears the linked list of all nodes
void List::Clear()
{
Node *temp = head; //store current head in temp
while(head != NULL)
{
head = head->getnext(); // set next head to head
delete temp; // delete current head in temp
}
}
Here is header file for the node class with functions:
#ifndef NODE_H
#define HODE_H
#include <iostream>
using namespace std;
// Here is the node class
class Node {
int student_id;
short test_one;
short test_two;
float average;
Node* next;
public:
Node(){}
void setnode(int student_id,short test_one,short test_two,float average)
{
student_id = student_id;
test_one = test_one;
test_two = test_two;
average = average;
}
void setnext(Node *link)
{
next = link;
}
void getnode( )const
{
cout << "The student's ID #: " << student_id << endl;
cout << "Score of Test One: " << test_one << endl;
cout << "Score of Test Two: " << test_two << endl;
cout << "The average: " << average << endl;
}
// returns address of the next node
Node* getnext()
{
return next;
}
};
#endif
Here is the header file for the class
#include "node.h"
#include <iostream>
class List
{
Node *head;
public:
List()
{
head = NULL;
}
void Insert();
void Remove();
void Clear();
void Display();
void Print(Node*);
};
Now what has to be done is a refactor of the following code so that:
"functions that are not accessed by the client should be private, mutator functions parameters are constant referenced, and all accessor functions are constants."
I've tired just switching to private, I've tried creating friends, and I have read something about runtime polymorphism and didn't try to implement because it did not seem to apply. I don't know where to start now because I'm under the impression that main.cpp is the client and it has to have access in order for this to work.
How would the above refactor ("functions that are not accessed by the client should be private, mutator functions parameters are constant referenced, and all accessor functions are constants.") work/look ?
After reading some of the comments and some more research. I've decided that setnode, getnode, getnext, setnext and Print should be private. They do not need any interaction with a user. Or I should say, that a user can incorrectly input parameters.
How about pass by reference ?
I'm starting to refactor but I'm still getting error's that the functions are private. Can anyone show a code snippet to refactor one of (or all that should be private) the functions to private so it works when its called by main.cpp ?
I made a linked list in C++. For in which I have a function named: ListTraverse(). Which accepts a Node type pointer variable, where Node is my class. Please suggest me a method where it prints up to the last node.
Here is function call:
ListTraverse(&head);
And here is the function definition:
void ListTraverse(Node* node)
{
//Prints upto penultimate node
while (node->next != NULL)
{
cout << "\nNode details:\t"
<< node->read_data();
node=node->next;
}
}
And here you have the entire code.
#include <bits/stdc++.h>
#include <stdlib.h>
#include<typeinfo>
using namespace std;
class Node
{
private:
int data;
public:
Node *next;
void push_data(int x)
{
data = x;
}
int read_data()
{
return data;
}
};
void ListTraverse(Node *);
int main()
{
system("CLS");
//Creating Node type variables
Node head, second, tail;
int num, choice;
//Getting user input
cout << "Enter a number for head:\t";
cin >> num;
head.push_data(num);
cout << "Enter a number for second:\t";
cin >> num;
second.push_data(num);
cout << "Enter a number for tail:\t";
cin >> num;
tail.push_data(num);
//Assigning pointers to link up
head.next = &second;
second.next = &tail;
tail.next = NULL;
cout << "If you want to read data press 1:\t";
cin >> choice;
switch (choice)
{
case 1:
ListTraverse(&head);
break;
default:
cout << "Invalid choice";
break;
}
return 0;
}
//Funtion to print Data
void ListTraverse(Node* node)
{
//Prints upto penultimate node
while (node->next != NULL)
{
cout << "\nNode details:\t"
<< node->read_data();
node=node->next;
}
}
You should re-phrase your question. It seems that
my function prints up to penultimate node only
is the problem.
you wanted to print the whole list, not penultimate. And the fix is
void ListTraverse(Node* node)
{
//Prints upto the last node
while (node)
{
cout << "\nNode details:\t"
<< node->read_data();
node=node->next;
}
}
I am using cin and cout in my program. I starts off fine because it is not executing any of the functions, but after you type your name, it throws an exception in the iostream library. wondering if it is a problem with using cin through refrence.`
// linkedlists.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <iostream>
#include <string>
using namespace std;
struct person {
string name;
int age;
struct person* next;
};
person *head = NULL;
int length() {
int count = 0;
person *current = head;
while (current->next != NULL) {
current = current->next;
count++;
}
return count;
}
void printlist() {
person *current = head;
while (current->next != NULL){
cout << "Name: " << current->name << " Age: " << current->age << "\n";
current = current->next;
}
}
void insert() {
// int choice;
person *newNode = (struct person*)malloc(sizeof(person));
//cout << "Press 1 to insert at beginning of list.\n";
//cin >> choice;
// switch (choice) {
//case 1:
newNode->next = head;
head = newNode;
cout << "What is this person's name?\n";
cin >> newNode->name;
cout << "\nWhat is the age of " << newNode->name << "?";
cin >> newNode->age;
cout << "The current list of people is " << length() << " long.\n";
printlist();
}
void menu() {
int choice;
cout << "Welcome to the person recorder! ";
bool inloop = true;
while (inloop) {
cout << "Press 1 to add more entries. Press 2 to print the entire list. Press 3 to exit the program.\n";
cin >> choice;
switch (choice) {
case 1:
insert();
case 2:
printlist();
case 3:
inloop = false;
}
}
}
/*void change(person* human) {
string temp_name;
int temp_age;
cout << "What is this person's name?\n";
cin >> temp_name;
cout << "\nWhat is this person's age?\n";
cin >> temp_age;
human->name = temp_name;
human->age = temp_age;
}
*/
int main()
{
menu();
}
using visual studio 2015, am a noob to c/c++ and trying to make a linked list.
The problem is caused by your allocation of person:
person *newNode = (struct person*)malloc(sizeof(person));
This will allocate memory on the heap for an instance of person, but it will not call the constructor of person and any of it's members. This does not matter for age and next since they are primitive types, but name is an std::string, which has a constructor that needs to be called for it to function properly.
In C++ you create instances of objects using the keyword new.
person *newNode = new person;
This will create a new instance of person, and also call its constructor, which will initialize name properly.
Once you are done with the instance of person, you will have use the keyword delete to clean it up.
delete newNode;
Similar to the difference between malloc and new, delete will free the memory, but also call the destructor, which is used by name to clean up any resources it may have allocated to store the string.
I am trying to add an element to the back of a linked list.
I am able to add the element and everything works fine on the first try but when i try to add another element, the previously added element becomes rubbish value.
The problem is solved when i replace the LinkedList::process_example(int choice,LinkedList &set) function in the main menu with exactly the same code in my function declaration. Can someone explain to me why????
#include <iostream>
#include <ctime>
using namespace std;
struct Node;
typedef void* VoidPtr;
typedef Node* NodePtr;
typedef char* ZodiacSign;
const int MAX=12;
struct Node
{
NodePtr next;
VoidPtr data;
};
class LinkedList
{
public:
LinkedList();
//~LinkedList();
void Addelement(VoidPtr);
void printSet();
int compareEqual(VoidPtr,VoidPtr);
void swap(int num,int x,ZodiacSign tempSign [MAX]);
void process_example(int choice);
int check_cardinality();
void Addelementfromback(VoidPtr);
private:
NodePtr head;
ZodiacSign getVP(VoidPtr);
};
int choice=1;
LinkedList set;
do {
cout<<endl
<<endl;
cout<<"Wish to try the following operation?"
<<endl
<<"1. Add an element to set"// the function to add to back of linked list
<<endl
<<"2. Check an element in set"
<<endl
<<"3. check carinality"
<<endl
<<"9. Quit"
<<endl
<<endl;
cout<<"Your choice : ";
cin>>choice;
cin.clear();
cin.ignore(200,'\n');
set.process_example(choice);
} while (choice !=9);
void LinkedList::process_example(int choice)
{
switch (choice)
{
case 1:
cout<<endl
<<endl
<<"Current S = ";
this->printSet();
cout<<"Enter an element :";
char element [30];
cin>>element;
cin.clear();
cin.ignore(200,'\n');
this->Addelementfromback(element);
cout<<endl
<<endl
<<"Current S = ";
this->printSet();
break;
case 3:
cout<<endl
<<endl;
cout<<"Current Set S = ";
set.printSet();
cout<<endl
<<"S has ";
int count=this->check_cardinality();
cout<<count
<<" elements";
}
}
void LinkedList::printSet()
{
NodePtr temp = head;
cout<<"{ ";
while (temp != NULL)
{
cout << getVP (temp -> data) << " , ";
temp = temp -> next;
}
cout<<" } ";
cout << endl;
}
void LinkedList::Addelementfromback(VoidPtr horoscope)
{
NodePtr temp = head;
while (temp->next != NULL)
{
temp=temp->next;
}
NodePtr element = new Node;
element->data=horoscope;
element->next=NULL;
temp->next=element;
}
As WhozCraig already mentioned you need to add the following lines to the constructor
Head = NULL;
and then you can add the something like this to the beginning of function Addelementfromback
If(Head == NULL)
{
Head = new Node;
Head->data = horoscope;
Head->next = NULL;
return;
}
you also need to change the following line in LinkedList::process_example
char elements[30];
to
char* elements = new char[30];
This question already has answers here:
getline not asking for input? [duplicate]
(3 answers)
Closed 7 years ago.
When I run this program, and select option 1, it prints both cout statements in void CTree::Add() at once, jumping over the cin.getline(newPerson->name, 20);
I had the same piece of code in linked list program and it behaved properly, I am really stuck at how to fix this.
//header file
using namespace std;
struct PersonRec
{
char name[20];
int bribe;
PersonRec* leftLink;
PersonRec* rightLink;
};
class CTree
{
private:
PersonRec *tree;
bool IsEmpty();
void AddItem( PersonRec*&, PersonRec*);
void DisplayTree(PersonRec*);
public:
CTree();
//~CTree();
void Add();
void View();
};
//implementation file`
#include <iostream>
#include <string>
using namespace std;
#include "ctree.h"
CTree::CTree()
{
tree = NULL;
}
//PersonList::~MyTree()
//{
//
//}
bool CTree::IsEmpty()
{
if(tree == NULL)
{
return true;
}
else
{
return false;
}
}
void CTree::Add()
{
PersonRec* newPerson = new PersonRec();
cout << "Enter the person's name: ";
cin.getline(newPerson->name, 20);
cout << "Enter the person's contribution: ";
cin >> newPerson->bribe;
newPerson->leftLink = NULL;
newPerson->rightLink = NULL;
AddItem(tree, newPerson);
}
void CTree::View()
{
if (IsEmpty())
{
cout<<"The list is empy";
}
else
{
DisplayTree(tree);
}
};
void CTree::AddItem( PersonRec*& ptr, PersonRec* newPer )
{
if (tree == NULL)
{
ptr = newPer;
}
else if ( newPer->bribe < ptr->bribe)
AddItem(ptr->leftLink, newPer);
else
AddItem(ptr->rightLink, newPer);
}
void CTree::DisplayTree(PersonRec* ptr)
{
if (ptr == NULL)
return;
DisplayTree(ptr->rightLink);
cout<<ptr->name<<" "<<"$"<<ptr->bribe <<endl;
DisplayTree(ptr->leftLink);
}
//driver file
#include <iostream>
using namespace std;
#include <cstdlib>
#include "ctree.h"
int displayMenu (void);
void processChoice(int, CTree&);
int main (void)
{
int num;
CTree ct;
do
{
num = displayMenu();
if (num != 3)
processChoice(num, ct);
} while (num != 3);
return 0;
}
int displayMenu (void)
{
int choice;
cout << "\nMenu\n";
cout << "==============================\n\n";
cout << "1. Add student to waiting list\n";
cout << "2. View waiting list\n";
cout << "3. Exit program\n\n";
cout << "Please enter choice: ";
cin >> choice;
return choice;
}
void processChoice(int choice, CTree& myTree)
{
switch (choice)
{
case 1: myTree.Add (); break;
case 2: myTree.View (); break;
}
}
After you read choice in the displayMenu subroutine, you leave the remainder of the user's input line. Specifically, you leave the end-of-line indicator: '\n'. Later, when you read newperson->name, you are actually retrieving the remainder of the menu line, and not the name line.
You can use istream::ignore to consume the rest of menu choice line, before trying to read the name.
Replace the last two lines of displayMenu with these:
cin >> choice;
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
return choice;
Adding a
cin.ignore(2000, '\n');
before the input call fixes the problem!