I am currently learning how to use linked list in class in my free time. Now I only know how to insert, display and delete. I can delete by using int age; but I think it would be better if I'm able to generate a unique ID that is easier for user to remember(user-friendly), for each data in the linked list so that I could delete by its ID.
I want to know if there is a possible way for me to generate a unique ID in the getInput(); function?
If yes, please give me a hint how to do it. Thanks!
struct list
{
list *head, *tail;
list *next;
}
class node
{
private:
std::string name; // Name
int age; // Age in integer
float height; // In meters
public:
node *next; // Pointer to next node
node *head, *tail;
node *start_ptr = NULL; // Start Pointer (root)
node *temp;
node *temp2;
node *pNextValue;
node* prev; // empty header
node* current;
void printList();
void delete_end_node();
void search();
void sort_age();
void deletebyAge();
node()
{
head = NULL;
tail = NULL;
}
void getInput()
{
temp = new node;
cout << "ID: ";
// This is where I want to generate unique ID
cout << "Name: ";
cin >> temp->name;
cout << "Age: ";
cin >> temp->age;
cout << "Height: ";
cin >> temp->height;
cout<<"\n";
temp->next = NULL; // Sets the node to be the last node
if (start_ptr == NULL)
start_ptr = temp;
else
{
temp2 = start_ptr; // We know temp2 is not NULL - list not empty!
while (temp2->next != NULL) // The loop will terminate when temp2
temp2 = temp2->next; // points to the last node in the list
// Move to next link in chain
temp2->next = temp; // Sets the pointer from that last node to point to the node that has just declared
}
} // End of getInput() function
}; //End of class
In C++ the identity of an object is its address. You can use node address as its id, e.g.:
class node
{
private:
std::string name; // Name
int age; // Age in integer
float height; // In meters
friend std::ostream& operator<<(std::ostream& s, node& n) {
return s << "id:" << &n
<< ' ' << "name:" << n.name
<< ' ' << "age:" << n.age
<< ' ' << "height:" << n.height
<< '\n';
}
// the rest of your code...
};
And then print it like:
node n;
std::cout << n;
Alternatively, use a serial counter:
class node
{
private:
std::string name; // Name
int age; // Age in integer
float height; // In meters
unsigned const id;
static unsigned object_counter;
public:
node()
: id(++object_counter)
{}
friend std::ostream& operator<<(std::ostream& s, node& n) {
return s << "id:" << n.id
<< ' ' << "name:" << n.name
<< ' ' << "age:" << n.age
<< ' ' << "height:" << n.height
<< '\n';
}
// the rest of your code...
};
unsigned node::object_counter = 0;
Related
#include <iostream>
#include <string.h>
using namespace std;
class MovieList {
private:
struct MovieNode {
string title;
struct MovieNode *next;
};
MovieNode *head;
public:
void appendNode(string var);
void displayList();
};
void MovieList::appendNode(string var) {
MovieNode *newNode, *nodePtr;
newNode = new MovieNode;
newNode->title = var;
newNode->next = NULL;
if (!head) {
head = newNode;
}
else {
nodePtr = head;
while (nodePtr->next)
nodePtr = nodePtr->next;
nodePtr->next = newNode;
}
cout << endl << "Input has been successfull!" << endl;
}
void MovieList::displayList() {
MovieNode *nodePtr;
if (head == NULL) {
cout << "The list is empty!" << endl;
}
else {
cout << "The nodes in the List are... " << endl;
nodePtr = head;
while (nodePtr) {
cout << nodePtr->title << endl;
nodePtr = nodePtr->next;
}
}
}
int main() {
MovieList list;
string var;
cout << " << Enter Movie >> " << endl << endl;
cout << "Enter a movie: ";
getline(cin, var);
list.appendNode(var);
list.displayList();
}
My question is why does the string variable won't show in the display void. The code is working at first when I try inputting a string but then it exits the program without displaying what I input. Is something wrong with how I put the string or is it in implementing the string into the node? please help, I'm new in linked list.
One issue is that MovieList.head is not initialized when you create a MovieList object.
Thus when MovieList.append() is called, this line:
if (!head)
causes the behavior of the program to be erratic due to the head pointer being whatever value it is, which you have no idea what the value is. It may be nullptr, thus the program works, but it may be any other values.
The bottom line is that you should initialize your member variables when you create an object. You can either create a default constructor that initialized head, or you can initialize head directly inline at the declaration point:
class MovieList
{
private:
struct MovieNode
{
string title;
struct MovieNode *next;
};
MovieNode *head;
public:
MovieList() : head(nullptr) {} // Using constructor
void appendNode(string var);
void displayList();
};
or:
class MovieList
{
private:
struct MovieNode
{
string title;
struct MovieNode *next;
};
MovieNode *head = nullptr; // Initialized here
public:
void appendNode(string var);
void displayList();
};
The Intro:
I'm working on a Project #Student Course Registration System,
my project is based on singly linked list, with file handling.
The Problem:
I have managed to modify the nodes in LinkedList, made a separate function to update my text file. But the problem is the file is not getting updated. On the console, I do see the items updated.
I have to work around modifying the text file without making a temporary one and copying items to that, which I know how to.
P.S : I have made a function which always loads all the required Text Files into the program at startup.
Structure:
struct Student {
string stdID;
string stdName;
string stdSemester;
Student *next;
};
Main:
int main() {
Student *Head = NULL;
Student *Tail = NULL;
Course *Headd = NULL;
Course *Taill = NULL;
UpdateDirectory(Head, Tail, Headd, Taill);
Display(Head, Tail);
_getch();
string Value;
getline(cin, Value);
ModifyStudent(Value, Head);
UpdateFile(Head, Tail);
//Display(Head, Tail);
return 0;
}
Modify Function:
void ModifyStudent(string Value, Student *&Head) {
// Initialize:
Student *Curr = NULL;
Student *Temp1 = NULL;
Student *Temp2 = NULL;
Student *Obj = new Student;
if (isEmpty(Head)) {
cout << "\t\t\t\t Underflow....\n\n";
_getch();
}
else {
Curr = Head;
Temp1 = Head;
while (Curr->stdID != Value) {
Temp1 = Curr;
Curr = Curr->next;
}
if (Curr->stdID == Value) {
cout << "\t\t\t\t Student Found!!\n\n";
cout << Curr->stdID << endl; // 1324
cout << Temp1->stdID << endl; // 3424
// Modify:
cout << "\t\t\t\t Enter New Student ID : ";
getline(cin, Obj->stdID);
cout << "\t\t\t\t Enter New Student Name : ";
getline(cin, Obj->stdName);
cout << "\t\t\t\t Enter New Semester : ";
getline(cin, Obj->stdSemester);
Temp1->next = Obj;
Obj->next = Curr->next;
Curr->next = NULL;
delete(Curr);
/// Save:
cout << "\t\t\t\t Record Is Being Updated, Please Wait.......\n\n" << endl;
_getch();
}
}
}
Update File:
void UpdateFile(Student *&Head, Student *&Tail) {
Student *Temp = NULL;
fstream SFile;
SFile.open("StudentRecords.txt", ios::trunc);
if (isEmpty(Head)) {
cout << "\t\t\t\t UnderFlow\n" << endl;
}
else {
Temp = Head;
while (Temp->next != NULL) {
cout << Temp->stdID << '\t' << Temp->stdName << '\t' << Temp->stdSemester << '\n';
SFile << Temp->stdID << '\t' << Temp->stdName << '\t' << Temp->stdSemester << '\n';
Temp = Temp->next;
}
cout << Temp->stdID << '\t' << Temp->stdName << '\t' << Temp->stdSemester << '\n';
SFile << Temp->stdID << '\t' << Temp->stdName << '\t' << Temp->stdSemester << '\n';
_getch();;
}
_getch();;
}
I have even used ios::trunc, but no effect.
Thank You!
It is hard to say what the problem is. You did not provide the full source code; therefore we cannot compile the code.
To write a file, use the following. The file will be overwritten (this seems to be what you are looking for):
ofstream os{ "test.txt" };
if( !os )
return -1;
if( !list.write( os ) )
return -2;
Regarding your code, this is a more c++ like approach to single linked lists:
Define a data class/structure. You may want to use the data with other classes, not only with a linked list, therefore keep it separated from node:
class student_t
{
public:
string id;
string name;
string semester;
// ...
};
Define operations. One of the operations you need is write:
ostream& write( ostream& os )
{
return os
<< id << endl
<< name << endl
<< semester << endl;
}
Define a node. A node is made of data and a pointer to next node:
class node_t
{
friend class list_t; // or replace it with public:
student_t data;
node_t* pnext;
// ...
};
Add a constructor and a write method:
node_t( const student_t& s, node_t* pnext ) : data{ s }, pnext{ pnext } {}
ostream& write_data( ostream& os )
{
return data.write( os );
}
Define a list class. The only data a list class holds is the list’s head. The class will gather all list operations like write_data, push_front, display_data, etc.
class list_t
{
node_t* phead{ nullptr };
public:
void push_front( const char* id, const char* name, const char* semester )
{
phead = new node_t( student_t{ id, name, semester }, phead );
}
ostream& write( ostream& os )
{
node_t* pn = phead;
while( pn && pn->write_data( os ) )
pn = pn->pnext;
return os;
}
//...
};
And this is how you use it:
int main()
{
list_t list;
list.push_front( "J1", "Jon", "first" );
list.push_front( "S1", "Steve", "first" );
{
ofstream os{ "test.txt" };
if( !os )
return -1;
if( !list.write( os ) )
return -2;
} // the file is automatically closed here
list.push_front( "A1", "Ava", "second" );
{
ofstream os{ "test.txt" };
if( !os )
return -1;
if( !list.write( os ) )
return -2;
}
return 0;
}
class Node {
public:
Node();
void setNext(Node*);
private:
void* item;
Node* next;
};
void Node::setNext(Node* n)
{
next = n;
}
class List {
public:
List();
void addFirst(void*);
void reset();
void* getCurItem();
private:
Node* head;
Node* current;
};
void List::addFirst(void* obj)
{
Node *newNode = new Node(obj);
newNode->setNext(head);
head = newNode;
}
void List::reset()
{
current = head;
}
void* List::getCurItem()
{
return current->getItem();
}
Polynomial::Polynomial(std::ifstream& input){
List *polyCo = new List();
List *polyEx = new List();
bool exit = false;
double coefficient=0;
int exponent=0;
while(!exit && input.good()){
input >> coefficient;
if(coefficient != -9999.99){
input >> exponent;
cout << "Exponent before: " << exponent << endl;
cout << "Coefficient before: " << coefficient << endl;
int *ExPtr = &exponent;
double *CoPtr = &coefficient;
cout << "Exponent: " << *(ExPtr) << endl;
cout << "Coefficient: " << *(CoPtr) << endl;
polyCo->addFirst(ExPtr);
polyEx->addFirst(CoPtr);
cout << polyCo->getCurItem() << endl; //SEG FAULT
}
}
polyEx->reset();
polyCo->reset();
}
I am reading numbers from a file into two separate linked lists. I am getting a segmentation fault when attempting to access the value in either of the linked list.
First, I'm going to outline how I think my addFirst() functions works, because I could just be implementing it incorrectly. When addFirst() is called, a new node is created, and the data being read in is set equal to the member of the new node. The existing node in the list is pushed forward, and the new node created becomes the head. The two nodes are also linked.
There could be something else entirely wrong besides my implementation of the function, but at least it is a good place to start, along with the source of the segmentation fault.
I'm using a class within a class and I'm getting errors, I think it's a linking problem. I get "undefined reference to 'Node::setlink()', 'Node::getlink()', and etc. It's all the node functions I used in linked_list.cpp that are the problem.
For example, linked_list.cpp:(.text+0x9de): undefined reference to
`Node::getlink()'
Linked_list.cpp
#include "linked_list.hpp"
#include "node.hpp"
#include <iomanip>
#include <iostream>
using namespace std;
//default constructor
Linked_list::Linked_list(void)
{
head = new Node();
tail = new Node();
head->setlink(NULL);
tail->setlink(NULL);
cnt = 0;
}
//constructor
Linked_list::Linked_list(data x)
{
head = new Node();
tail = new Node();
Node *newnode = new Node(x);
head->setlink(newnode);
newnode->setlink(tail);
cnt++;
}
//class function
void Linked_list::insert_node(data x)
{
Node *newNode = new Node(x);
Node *prev = new Node();
Node *curr = new Node();
if (head == NULL)
{
newNode->setlink(tail);
head->setlink(newNode);
}
else if (head != NULL)
{
prev->setlink(head);
curr->setlink(head->getlink());
while(curr->getlink() != NULL || newNode->getupc() <= curr->getupc())
{
prev->setlink(curr);
curr->setlink(curr->getlink());
}
prev->setlink(newNode);
newNode->setlink(curr);
}
cnt++;
}
//Class function
void Linked_list::delete_node(int u)
{
char choice;
data temp;
Node *newNode = new Node();
Node *prev = new Node();
Node *curr = new Node();
if (head == NULL)
{
delete newNode;
delete prev;
delete curr;
}
else if (head != NULL)
{
prev->setlink(head);
curr->setlink(head->getlink());
while (curr->getlink() != NULL || curr->getupc() != u )
{
prev->setlink(curr);
curr->setlink(curr->getlink());
}
temp = curr->get_structure();
cout << temp.UPC << setw(15) << temp.desc << setw(15) << "$" << temp.cost << setw(15) << "Aisle: " << temp.aisle << endl;
prev->setlink(curr->getlink());
cout << "Are you sure you want to delete?\n";
cin >> choice;
if (choice == 'y' || choice == 'Y')
{
delete curr;
cnt--;
}
else
{
choice = 'n';
}
}
}
//Class function
void Linked_list::traverse()
{
data temp;
Node *curr = new Node();
if (head == NULL)
{
delete curr;
cout << "The list is empty!\n";
}
else
{
curr->setlink(head->getlink());
while(curr->getlink() != NULL)
{
temp = curr->get_structure();
cout << temp.UPC << setw(15) << temp.desc << setw(15) << "$" << temp.cost << setw(15) << "Aisle: " << temp.aisle << endl;
}
}
}
void Linked_list::retrieve_node(int u)
{
data temp;
Node *x;
x = new Node();
if (head == NULL)
{
delete x;
}
else if (head != NULL)
{
x->setlink(head->getlink());
while (x->getlink() != NULL || x->getupc() != u)
{
x->setlink(x->getlink());
}
temp = x->get_structure();
cout << temp.UPC << setw(15) << temp.desc << setw(15) << "$" << temp.cost << setw(15) << "Aisle: " << temp.aisle << endl;
}
}
void Linked_list::check_empty()
{
if (head != NULL)
{
cout << "The list is empty.\n";
}
else
{
cout << "The list is not empty.\n";
}
}
linked_list.hpp
#include "node.hpp"
#ifndef linked_list_hpp
#define linked_list_hpp
class Linked_list
{
Node *head;
Node *tail;
int cnt;
public:
//default constructor creates empty linked list
Linked_list(void);
//Constructor that creates first node with values
Linked_list(data x);
//Inserts node at correct spot
void insert_node(data x);
//deletes specific node
void delete_node(int u);
//goes through whole list and prints out
void traverse(void);
//returns specific node
void retrieve_node(int u);
//checks if list is empty
void check_empty();
return_number();
};
#endif
node.hpp
#ifndef node_hpp
#define node_hpp
#include "node.hpp"
#include <string>
using namespace std;
struct data
{
int UPC;
string desc;
int quantity;
double cost;
int aisle;
};
class Node
{
data item;
Node *link;
public:
Node(void);
Node(data x);
void setlink(Node *ptr);
Node* getlink();
int getupc();
data get_structure();
bool compare_item(string i);
double processdata();
};
#endif
node.cpp
#include "node.hpp"
Node::Node(void)
{
link = NULL;
}
Node::Node(data x)
{
item = x;
}
void Node::setlink(Node *ptr)
{
link = ptr;
}
Node* Node::getlink()
{
return link;
}
int Node::getupc()
{
return item.UPC;
}
data Node::get_structure()
{
return item;
}
bool Node::compare_item(string i)
{
if(i==item.desc)
{
return true;
}
else
{
return false;
}
}
double Node::processdata()
{
return item.cost*item.quantity;
}
main function
#include <iostream>
#include "node.cpp"
#include "linked_list.cpp"
using namespace std;
void fromfile(Linked_list &x);
void tofile(Linked_list &x);
int main(void)
{
Linked_list ll;
int x, y;
data a;
do
{
cout << "1.Add a grocery item\n" ;
cout << "2.Delete an item\n";
cout << "3.Retrieve an item\n";
cout << "4.Traverse the list forwards and print out all of the items\n";
cout << "5. Exit the program.\n";
cin >> x;
switch(x)
{
case 1:
cout << "Enter UPC code\n";
cin >> a.UPC;
cout << "Enter description(name of item)\n";
cin >> a.desc;
cout << "Enter quantity\n";
cin >> a.quantity;
cout << "Enter cost\n";
cin >> a.cost;
cout << "Enter aisle\n";
cin >>a.aisle;
ll.insert_node(a);
case 2:
cout << "Enter UPC of item you'd like to delete.\n";
cin >> y;
ll.delete_node(y);
case 3:
cout << "Enter UPC code.\n";
cin >> y;
ll.retrieve_node(y);
case 4:
ll.traverse();
case 5:
cout << "Bye!\n";
default:
cout << "Wrong choice, try again!\n";
}
}while (x != 5);
return 0;
}
Please help me out, this is due in 2 hours. I think I got it running somehow for a while and after the code performs in main, it just stop creating output after it reaches a linked_list function. Then, I can't enter anything afterwards.
The only thing not compiling is the linked_list.cpp, and I get a winmain error as well.
It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 10 years ago.
So Im trying to make a double linked list that I can search for the name and also search for people only below a certain age, but I dont know how to do that. So far Ive only got the one but Im having trouble.
#include <iostream>
#include <string>
using namespace std;
typedef string Elem; // list element type
class DNode { // doubly linked list node
private:
Elem elem; // node element value
int age;
DNode* prev; // previous node in list
DNode* next; // next node in list
friend class DLinkedList; // allow DLinkedList access
};
class DLinkedList { // doubly linked list
public:
DLinkedList(); // constructor
~DLinkedList(); // destructor
bool empty() const; // is list empty?
const Elem& front() const; // get front element
const Elem& back() const; // get back element
void addFront(const Elem& name); // add to front of list
void addBack(const Elem& name); // add to back of list
void removeFront(); // remove from front
void removeBack(); // remove from back
void displayViaAge(string age);
void displayViaName(const Elem& name);
void removeName(const Elem& name);
private: // local type definitions
DNode* header; // list sentinels
DNode* trailer;
protected: // local utilities
void add(DNode* v, const Elem& name); // insert new node before v
void remove(DNode* v); // remove node v
};
DLinkedList::DLinkedList() { // constructor
header = new DNode; // create sentinels
trailer = new DNode;
header->next = trailer; // have them point to each other
trailer->prev = header;
}
DLinkedList::~DLinkedList() { // destructor
while (!empty()) removeFront(); // remove all but sentinels
delete header; // remove the sentinels
delete trailer;
}
// insert new node before v
void DLinkedList::add(DNode* v, const Elem& name) {
DNode* u = new DNode;
u->elem = name; // create a new node and set name
u->next = v; // make v the successor of u
u->prev = v->prev; // set u's predecessor to v's current predecessor
u->prev->next = u; // make u the successor of v's predecessor
v->prev = u; // finally make u the predecessor of v
}
/*
void DLinkedList::removeName(const Elem& name) {
DNode* u = new DNode; u->elem = name; // create a new node and set name
u->next = v; // make v the successor of u
u->prev = v->prev; // set u's predecessor to v's current predecessor
u->prev->next = u; // make u the successor of v's predecessor
v->prev = u; // finally make u the predecessor of v
}
*/
void DLinkedList::addFront(const Elem& name) // add to front of list
{ add(header->next, name); }
void DLinkedList::addBack(const Elem& name) // add to back of list
{ add(trailer, name); }
void DLinkedList::remove(DNode* v) { // remove node v
DNode* u = v->prev; // predecessor
DNode* w = v->next; // successor
u->next = w; // unlink v from list
w->prev = u;
delete v;
}
void DLinkedList::removeFront() // remove from font
{ remove(header->next); }
void DLinkedList::removeBack() // remove from back
{ remove(trailer->prev); }
bool DLinkedList::empty() const // is list empty?
{ return (header->next == trailer); }
const Elem& DLinkedList::front() const // get front element
{ return header->next->elem; }
const Elem& DLinkedList::back() const // get back element
{ return trailer->prev->elem; }
void DLinkedList::displayViaAge(string age) { //Displays person via age
//int check = 0;
DNode*temp = header;
while(temp!=trailer)
{
// age = str.find(temp->elem);
// if(check == 1){
cout << temp->elem <<endl;
temp = temp -> next;
// }
}
cout << temp->elem<<endl;
}
void DLinkedList::displayViaName(const Elem& name) { //Displays person via age
int check = 0;
DNode*temp = header;
while(temp!=trailer)
{
if(temp->elem == name){
cout << "Yes that Person is in out system" << endl;
check = 1;
}
temp = temp -> next;
}
if(temp->elem == name){
cout << "Yes that Person is in out system" << endl;
check = 1;
}
if(check == 0){ cout << "Sorry that person is not in our system" << endl;}
check = 0;
}
class Person {
public:
void print();
string getName();
int getAge();
private:
string name;
int age;
};
int main(){
char input = 'z';
string entry;
int age;
DLinkedList person;
person.addFront("Takkun Bradly 19");
person.addFront("Devindra Ardnived 18");
person.addFront("SeboY Wang 20");
person.addFront("DoubleX Slash 31");
person.addFront("Uncle Jelly 17");
person.addFront("test 12");
cout << "What would you like to do?" << endl;
cout << "Enter 'A' to: Add a new person" << endl;
cout << "Enter 'B' to: Remove a person" << endl;
cout << "Enter 'C' to: Search for people via age" << endl;
cout << "Enter 'D' to: Search for people via name" << endl;
cout << "Enter 'E' to: Average all the total ages" << endl;
cout << "Enter 'F' to: Quit" << endl;
while(input != 'f') {
cin >> input;
cout << endl;
while ((input != 'a')&&(input != 'b')&&(input != 'c')&&(input != 'd')&&(input != 'e')&&(input != 'f')) {
cout << "Please enter a valid selection" << endl;
cin >> input;
}
if ((input == 'a')){
cout << "Please enter their name and age: ";
cin.ignore();
getline(cin, entry);
person.addFront(entry);
}
if ((input == 'b')){
cout << "Who would you like to remove: ";
cin.ignore();
getline(cin, entry);
person.removeFront();
}
if ((input == 'c')){
cout << "What is the age of the person you are looking for?: ";
cin.ignore();
getline(cin, entry);
person.displayViaAge(entry);
}
if ((input == 'd')){
cout << "What is the name of the person you are looking for?: ";
cin.ignore();
getline(cin, entry);
person.displayViaName(entry);
}
if ((input == 'e')){
cout << "The total average of ages are: " << endl;
}
cout << endl;
}
}
You've taken several things you don't know how to do, and welded them together into a problem you don't know how to solve.
You seem to assume that a name has two parts. Fine:
if ((input == 'a')){
cout << "Please enter their name and age: ";
cin.ignore();
cin >> firstName >> secondName >> age;
...
}
Then if you really want to store the name as a single string,
name = firstName + " " + secondName;
Now to create a new member of the list:
person.addFront(name, age);
This calls:
void DLinkedList::add(DNode* v, const Elem& name, int age)
The underlying problem here is that you knew you should handle name and age as separate variables, but you didn't know how, so instead of finding out how you wrote a kludge, something that you did know how to do. And pretty soon you were trapped. Learn to listen to that little voice.