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.
Related
I want to update a data in the node of the linked list. I have tried to but it does not changed the data within. If anyone can help me with this, i would be really appreciated.
This is my Main Driver Code
#include <iostream>
#include <fstream>
#include <string>
#include "item.h"
using namespace std;
LinkedList list;
Item item;
Node* node;
void menu()
{
here:
int choice = 0;
string itemId, title, type, loan, num_copy, fee, genre;
cout << "Welcome to Genie\'s video store" << endl;
cout << "Enter an option below" << endl;
cout << "1. Add a new item" << endl;
cout << "2. Delete an item" << endl;
cout << "3. Update an item" << endl;
cout << "4. Search an item by ID" << endl;
cout << "5. Search an item by title" << endl;
cout << "6. Display all item" << endl;
cout << "Exit" << endl;
cout << "Enter your choice: ";
cin >> choice;
if (choice == 1)
{
system("cls");
list.addItem(list);
cout << endl;
goto here;
}
else if (choice == 2)
{
system("cls");
list.deleteItem(list);
cout << endl;
goto here;
}
else if (choice == 3)
{
system("cls");
list.updateItem(list);
cout << endl;
goto here;
}
else if (choice == 4)
{
system("cls");
list.searchById(list);
cout << endl;
goto here;
}
else if (choice == 5)
{
system("cls");
list.searchByTitle(list);
cout << endl;
goto here;
}
else if (choice == 6)
{
system("cls");
list.printAll(list);
cout << endl;
goto here;
}
}
int main(int argc, char* argv[])
{
ifstream file("items.txt", ios::in);
if (!file)
{
cerr << "Error in opening file.";
throw(file);
}
list.readAllFile(file, list);
file.close();
menu();
return 0;
}
And this is my item.h:
#pragma once
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
class Item
{
protected:
string itemId, title, type, loan, num_copy, fee, genre;
public:
Item() {}
Item(string itemId, string title, string type, string loan, string num_copy, string fee, string genre)
: itemId(itemId), title(title), type(type), loan(loan), num_copy(num_copy), fee(fee), genre(genre)
{}
~Item() {}
string& getItemId() { return this->itemId; }
string& getTitle() { return this->title; }
string& getType() { return this->type; }
string& getLoan() { return this->loan; }
string& getCopy() { return this->num_copy; }
string& getFee() { return this->fee; }
string& getGenre() { return this->genre; }
void setItemId(string itemId) { this->itemId = itemId; }
void setTitle(string title) { this->title = title; }
void setFee(string fee) { this->fee = fee; }
void setCopy(string num_copy) { this->num_copy = num_copy; }
void setLoan(string loan) { this->loan = loan; }
void setType(string type) { this->type = type; }
void setGenre(string genre) { this->genre = genre; }
};
class Node
{
private:
Item data;
Node* next;
public:
Node() {}
Node(Item newData)
{
data = newData;
next = nullptr;
}
Node(Item newData, Node* nextNode)
{
data = newData;
next = nextNode;
}
~Node() {}
Node* getNext() { return next; }
void setNext(Node* newNext) { next = newNext; }
Item getData() { return data; }
Item setData(Item newData) { data = newData; }
Node* createNode(Item newData);
};
class LinkedList
{
private:
Node* head;
Node* tail;
public:
LinkedList() : head(NULL), tail(NULL)
{}
~LinkedList() {}
void createList(LinkedList& list);
void insertHead(LinkedList& list, Node* temp);
void appenTail(LinkedList& list, Node* temp);
void readLine(ifstream& file, Item& item);
void readAllFile(ifstream& file, LinkedList& list);
void printOneLine(Item item);
void printAll(LinkedList list);
//void writeToFile(LinkedList& list);
void addItem(LinkedList& list);
void deleteItem(LinkedList list);
void updateItem(LinkedList& list);
void searchById(LinkedList list);
void searchByTitle(LinkedList list);
};
Finally, this is my item.cpp file:
void LinkedList::updateItem(LinkedList& list)
{
string updateId, updateTitle, updateType, updateLoan, updateNumCopy, updateFee, updateGenre;
Node node;
Node* temp = list.head;
bool found = false;
if (temp == nullptr)
{
cerr << "There are no items." << endl;
exit(EXIT_FAILURE);
}
cout << "Enter the item's id and other info you want to update below:" << endl;
cout << "ID: ";
cin.ignore();
getline(cin, updateId);
cout << "Title: ";
cin.ignore();
getline(cin, updateTitle);
cout << "Type: ";
cin.ignore();
getline(cin, updateType);
cout << "Loan type: ";
cin.ignore();
getline(cin, updateLoan);
cout << "Copy(s): ";
cin.ignore();
getline(cin, updateNumCopy);
cout << "Rental fee: ";
cin.ignore();
getline(cin, updateFee);
cout << "Rental genre: ";
cin.ignore();
getline(cin, updateGenre);
while (temp != nullptr)
{
Item item = temp->getData();
if ((_stricmp(item.getItemId().c_str(), updateId.c_str()) == 0) || (_stricmp(item.getTitle().c_str(), updateTitle.c_str()) == 0))
{
item.getItemId() = updateId;
item.getTitle() = updateTitle;
item.getType() = updateType;
item.getLoan() = updateLoan;
item.getFee() = updateFee;
item.getGenre() = updateGenre;
found = true;
}
temp = temp->getNext();
}
if (!found)
{
cerr << "Item not found." << endl;
exit(EXIT_FAILURE);
}
}
So the main problem is that inside the updateItem() function, we do not know how to make the function to update a specific variables of the object. I have tried the above updateItem function and the final result is that none of the item's information is changed.
Thank you.
Item item = temp->getData();
getData returns a copy and it is stored inside a new variable. You are making changes but it is not in the right variable. One solution would be to store and return a reference:
// return a reference
Item & getData() { return data; }
// store a reference
Item & item = temp->getData();
so I'm writing a program that receives string input from user and performs some basic operations on that such as getlength, get index, append to another string and test if it sub match. Most of my code is base on my professor's sample code, I just write extra methods to performs the operations that I listed earlier. However, I receives the error from LinkedChar.h and Node.h that I repeatedly made but couldn't find solutions. I will note the big ERRORS! word in the comment section in my code.
#include <iomanip>
#include "LinkedChar.h"
// Function prototype
bool isCreated(const LinkedChar<char>* charPtr);
LinkedChar<char> toLinkedChar(const string &items);
/************************************************************************
* main *
************************************************************************/
int main()
{
bool done = false; // A finish flag
int choice; // Menu choice
cout << " This program solves an ADT character string. \n";
LinkedChar<char>* charPtr = nullptr;
string firstString;
char aChar;
while (!done)
{
// Display the menu and get the user's choice
cout << "=========================================================\n"
<< "Operations\n\n";
cout << setw(5) << "1. New the first string\n";
cout << setw(5) << "2. Get the length from the first string\n";
cout << setw(5) << "3. Find index of character in the first string\n";
cout << setw(5) << "4. Append another string to the first string\n";
cout << setw(5) << "5. Test if another string is submatch of the first string\n";
cout << setw(5) << "6. Quit\n"
<<"=========================================================\n\n";
cout << "Enter your Choice (1-6): ";
cin >> choice;
cin.ignore();
// Validate and process the menu choice
if (choice == 1)
{
cout << "Please enter a string: ";
getline(cin, firstString);
charPtr = new LinkedChar<char>(firstString);
cout << "The first string has been created. \n\n";
}
else if (choice == 6)
{
// Set the program is finished
done = true;
}
else if (choice > 1 && choice < 6)
{
if (isCreated(charPtr))
// Execute the correct set of actions
switch (choice)
{
case 2:
cout << "The length of the first string \"" << charPtr->toString() << "\" is " << charPtr->length() << ".\n\n";
break;
case 3:
cout << "Please enter a character to find: ";
cin >> aChar;
cout << "The index of \"" << aChar << "\" is " << charPtr->index(aChar) << "\n\n";
break;
case 4:
cout << "Please enter another string to append: ";
getline(cin, firstString);
charPtr->append(toLinkedChar(firstString));
cout << "The string changes to \"" << charPtr->toString() << "\".\n\n";
break;
case 5:
cout << "Please enter another string to test: ";
getline(cin, firstString);
cout << "The string \"" << firstString << "\" is ";
if (!charPtr->submatch(toLinkedChar(firstString)))
cout << "not ";
cout << "submatch of the first string \"" << charPtr->toString() << "\".\n\n";
break;
}
}
else
{
cout << "The valid choices are 1 through 6.\n\n";
}
}
return 0;
}
bool isCreated(const LinkedChar<char>* charPtr)
{
if (charPtr == nullptr)
{
std::cout << "Please choose 1 to create the first string before start!\n\n";
return false;
}
else
{
return true;
}
}
LinkedChar<char> toLinkedChar(const string &items)
{
return LinkedChar<char>(items);
}
Node.h
#ifndef NODE_H
#define NODE_H
template<class ItemType>
class Node
{
private:
ItemType item;
Node<ItemType>* next; // Pointer to next node
public:
Node() {
next = nullptr;
}
Node(const ItemType& anItem)
{
// ----------- ERRORS ------------//
item(anItem); //Called object type 'char' is not a function or function
//pointer
next(nullptr); //Called object type 'Node<char> *' is not a function or
//function pointer
/*This copy constructor is also exposed an error that I
could not understand. I think that I declare the item as a
template so later I could determine that datatype for item is
either string or char*/
// --------------------------------//
}
Node(const ItemType& anItem, Node<ItemType>* nextNodePtr)
{
item(anItem);
next(nextNodePtr);
}
void setItem(const ItemType& anItem)
{
item = anItem;
}
void setNext(Node<ItemType>* nextNodePtr)
{
next = nextNodePtr;
}
ItemType getItem() const {
return item;
}
Node<ItemType>* getNext() const {
return next;
}
}; // end Node
#endif
LinkedChar.h
// Created by
//
#ifndef LINKEDCHAR_H
#define LINKEDCHAR_H
#include <iostream>
#include <string>
#include "Node.h"
using namespace std;
template<class ItemType>
class LinkedChar
{
private:
Node<ItemType>* headPtr;
int itemCount;
public:
LinkedChar() {
headPtr = nullptr;
itemCount = 0;
}
LinkedChar(string items) {
itemCount = int(items.size());
headPtr = nullptr;
for (int i = itemCount - 1; i >= 0; i--)
{
if (headPtr == nullptr)
{
// Copy first node
headPtr = new Node<ItemType>();
headPtr->setItem(items[i]);
} else {
// Create a new node containing the next item
Node<ItemType>* newNodePtr = new Node<ItemType>(items[i]);
newNodePtr->setNext(headPtr); // New node points to chain
headPtr = newNodePtr; // New node is now first node
}
}
}
virtual ~LinkedChar() {
clear();
}
int length() {
return itemCount;
}
int index(const ItemType& anItem) const {
int index = 0;
Node<ItemType>* curPtr = headPtr;
while (curPtr != nullptr)
{
if (anItem == curPtr->getItem())
{
return index;
} // end if
index++;
curPtr = curPtr->getNext();
}
return -1;
}; // -1 if no match
void append(const LinkedChar& lc) {
// -------------- ERRORS ------------------ //
itemCount += lc.length(); // This is when I got the error guys, it says
// " 'this' argument to member function 'length' has
//type 'const LinkedChar<char>', but function is not
marked const "
// ------------------------------------------//
Node<ItemType>* newChainPtr = headPtr;
while (newChainPtr != nullptr && newChainPtr->getNext() != nullptr)
{
newChainPtr = newChainPtr->getNext();
}
Node<ItemType>* origChainPtr = lc.headPtr;
while (origChainPtr != nullptr)
{
// Get next item from original chain
ItemType nextItem = origChainPtr->getItem();
// Create a new node containing the next item
// ---------------- ERRORS -------------------- //
Node<ItemType>* newNodePtr = new Node<ItemType>(nextItem);
^^
||
||
// ERROR: The Error of no matching constructor for initialization of Node<Char>
//This happens to me alot previously, my solution is just put new Node(' ')
//But in this case seem inappropriate
// --------------------------------------------- //
// Link new node to end of new chain
newChainPtr->setNext(newNodePtr);
// Advance pointer to new last node
newChainPtr = newChainPtr->getNext();
// Advance original-chain pointer
origChainPtr = origChainPtr->getNext();
}
newChainPtr->setNext(nullptr);
}
bool submatch(const LinkedChar& lc) const {
bool found = false;
Node<ItemType>* curPtr = headPtr;
Node<ItemType>* origChainPtr = lc.headPtr;
ItemType anItem;
while (origChainPtr != nullptr && curPtr != nullptr)
{
anItem = origChainPtr->getItem();
while (curPtr != nullptr)
{
if (anItem == curPtr->getItem())
{
found = true;
curPtr = curPtr->getNext();
break;
}
else if (found)
{
found = false;
break;
}
curPtr = curPtr->getNext();
}
if (!found)
origChainPtr = lc.headPtr;
else
origChainPtr = origChainPtr->getNext();
}
return found && (origChainPtr == nullptr);
}
void clear() {
Node<ItemType>* curPtr = headPtr;
while (headPtr != nullptr)
{
headPtr = headPtr->getNext();
// Return node to the system
curPtr->setNext(nullptr);
delete curPtr;
curPtr = headPtr;
}
itemCount = 0;
}
string toString() const {
std::string aString;
Node<ItemType>* curPtr = headPtr;
while ((curPtr != nullptr))
{
aString += (curPtr->getItem());
curPtr = curPtr->getNext();
}
return aString;
}
};
//#include "LinkedChar.cpp"
#endif //LINKEDCHAR_H
You're getting overwhelmed by error messages. You should take each one in turn, starting with the first. Understand what it's telling you. Fix it, recompile to make sure. And move on to the next one.
For starters:
Make length() const
int length() const {
Change
next(nullptr);
to
setNext(nullptr);
Change
item(anItem);
to
setItem(anItem);
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;
}
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;
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.