Weird segfault in C++ - c++

I am checking data of head node in constructor and its ok, but when i am checking it in the function then its gone. Why is it such a ghost this pointer ?
header for queue
#ifndef QUEUE_H
#define QUEUE_H
#include "Node.h"
#include "LinkedList.h"
class Queue
{
public:
Queue();
~Queue();
void addTail(Node* newNode);
Node* deleteHead();
int isEmpty();
void PrintQueue(char* outName);
protected:
private:
Node* head;
Node* tail;
LinkedList* myList;
};
#endif // QUEUE_H
queue class
#include "Queue.h"
Queue::Queue()
{
//constructor
myList = new LinkedList();
head = myList->getHead();
std::cout<<" head here is " << head->getData()<<std::endl; //
std::cout<<" next after head is " << head->getNext()->getData()<<std::endl; //
tail = myList->getTail();
}
void Queue::addTail(Node* newNode)
{
std::cout<<"inserting before tail (queue)"<<std::endl;
std::cout<<"new node is " << newNode->getData() <<std::endl;
std::cout<<" head here is " << myList->getHead()->getData() <<std::endl;
myList->insertLast(newNode);
}
Node* Queue::deleteHead()
{
if(isEmpty()){
std::cout<<"Queue is empty. Cannot remove anything anymore. Add more data to the queue!"<<std::endl;
return head;
}
return myList->removeFirst();
}
int Queue::isEmpty()
{
return myList->isEmpty();
}
void Queue::PrintQueue(char* outName)
{
Node* cur = head->getNext(); //store current node to keep track. Set it to one after the head
std::ofstream outfile;
outfile.open(outName, std::ios::app);
outfile << "Printing the values of the queue: ";
std::cout<<"Printing the values of the queue: "<<std::endl;
while(cur != tail)
{
std::cout<< cur->getData()<<", "<<std::endl; //print to the console
outfile << cur->getData() <<", "; //print to file
}
outfile.close();
}
Queue::~Queue()
{
//destructor
delete myList;
}
Main function
#include <iostream>
#include <fstream>
#include <string>
#include "Stack.h"
//#include "Stack.cpp"
#include "LinkedList.h"
//#include "LinkedList.cpp"
#include "Node.h"
//#include "Node.cpp"
#include "HashTable.h"
//#include "HashTable.cpp"
using namespace std;
int main( int argc, char* argv[] )
{
//specifying the in and out files
char* inFileName = argv[1];
char* outFileName = argv[2];
std::fstream infile (inFileName) ; // input file
//open the input file and find largest integer
int num;
int largest = 0;
Stack * myStack = new Stack();
char buffer[33]; //create a buffer for using with itoa
std::ofstream outfile;
outfile.open(outFileName);
if ( !infile.is_open() ) //check if input file is open
cout<<"Could not open file\n";
else {
while (infile >> num) { // read file int by int and check if current is not the largest
if(num > largest) largest = num;
Node *newNode= new Node(itoa(num,buffer,10));
myStack->push(newNode);
}
}
std::cout<< std::endl;
infile.close(); //close files that you read to avoid memory leaks
myStack->PrintStack(outFileName);
HashTable* hashBrown = new HashTable();
int currentDigit = 0;
int currentTable = 0;
int numOfDig =0; //stores number of digits of the largest number
string maxNum = itoa(largest,buffer,10);
numOfDig = maxNum.length();
std::cout<< "Num of digits " << numOfDig << std::endl;
Node* current;
while(!myStack->isEmpty())
{
current = myStack->pop();
std::cout<< "pop from stack element " << current->getData() << std::endl;
string str = current->getData();
int index = atoi(&str.back());
std::cout<< "insert at index " << index << std::endl;
std::cout<< "inserting data: "<< current->getData()<< " at index:" << index << std::endl;
hashBrown->myQueues[index].addTail(current);
}
hashBrown->printHashTable(outFileName);
delete myStack;
delete hashBrown;
outfile.close();
std::cout<< "finishing program " << std::endl;
return 0;
}
Linked List
#include "LinkedList.h"
#include "Node.h"
LinkedList::LinkedList()
{
//constructor
head = new Node("head"); //dummy variable
tail = new Node("tail"); //dummy variable
head->setNext(tail);
}
void LinkedList::insertNode(Node* newNode, Node *position)
{
newNode->setNext(position->getNext()); // set its pointer to position
position->setNext(newNode);
}
void LinkedList::insertFirst(Node* newNode)
{
std::cout<<"head here is "<< head->getData() <<std::endl; //
insertNode(newNode, head);
}
void LinkedList::insertLast(Node* newNode)
{
std::cout<<"inserting before tail (LinkedList)"<<std::endl; //
Node* cur = head;
std::cout<<"outside the loop "<< cur->getData() <<std::endl; //
std::cout<<"current node is "<< cur->getData() <<std::endl; //
while(cur->getNext() != tail) //iterate until you reach one before tail
{
std::cout<<"current node is "<< cur->getData() <<std::endl; //
cur = cur->getNext();
}
std::cout<<"inserting before tail"<<std::endl; //
insertNode(newNode, cur); //insert at the end before the dummy tail
}
Node* LinkedList::removeFirst()
{
if(isEmpty())
{
return head;
}
Node* result = head->getNext(); //store pointer to Node that you need to return
head->setNext(result->getNext());
return result;
}
Node* LinkedList::getTail()
{
return tail;
}
Node* LinkedList::getHead()
{
return head;
}
int LinkedList::isEmpty()
{
return head->getNext() == tail;
}
std::string LinkedList::printList(){
Node *current = head;
std::string str;
//append pieces of string to create new line
while(current != tail){
str.append (" --> (");
str.append ( current->getData());
str.append (",");
str.append (current->getNext()->getData());
str.append (")") ;
current = current->getNext();
}
std::cout<<str<<std::endl; //display new
return str; //return string containing next line that will be written to a file in main
}
LinkedList::~LinkedList()
{
//destructor
Node *current = head;
while( current->getNext() != tail ) { //go through whole linked list and delete each node to free memory
Node* next = current->getNext();
delete current;
current = next;
}
delete current;
delete tail;
}
So everything works fine until it tries to access the head or its data in the addTail() function of Queue.

You can use gdb to debug your program, find the bugs and fix them. If the program cored, you can use backtrace to see what caused the core.
Set breakpoint at the lines you think program behavior wired, you can also let the program run step by step.
Run the program and print variable value to see whether the variable value is expected. If the variable is a pointer, you can also print the content it referenced.
A brief gdb tutorial

Related

Returning an object from dequeue function?

I am trying to get a linked-list class-based queue that holds objects of type "Student", but I've been trying for two days to get this thing to work. Now I am seeing errors of exceptions at the copy constructor of the "Student" class and the return of the dequeue function, and am at a complete loss since I don't even know what that means.
My main issue, from what I can tell, is when I try to assign the return of the dequeue to an object, there is an issue with the fact that I'm using the standard = operator and not a custom operator= for the class. Then again, I am relatively new to classes so I don't know if this is actually the issue.
This is the main code that uses all my files:
#include <iostream>
#include <fstream>
#include <string>
#include "Student.h"
#include "Queue.h"
int main(void)
{
char TempFName[15], TempSName[20];
long Tid_num;
int Tage;
float Tgpa;
Student Student1, StudentA;
queue q1;
int no, temp;
ifstream ip("input.txt");
// modify for your location
ip >> no; /* read in the number of Students */
for (temp = 0; temp < no; temp++)
{
/* read in the Student data in file format */
ip >> TempFName;
Student1.assignFName(TempFName);
ip >> TempSName;
Student1.assignSName(TempSName);
ip >> Tid_num;
Student1.assignId(Tid_num);
ip >> Tage;
Student1.assignAge(Tage);
ip >> Tgpa;
Student1.assignGpa(Tgpa);
q1.enqueue(Student1);
}
ip.close();
queue q2(q1);
q2.enqueue(StudentA);
q1.enqueue(StudentA);
cout << "details for queue 2 are as follows" << endl;
for (temp = 0; temp < no + 1; temp++)
{
Student1 = q2.dequeue();
Student1.print();
}
cout << "There are " << Student1.getNum() << " Student objects in existence";
return 0;
}
My files are:
Student.cpp:
#include <iostream> // need for cout, etc
#include "Student.h"
using namespace std;
Student::Student(const Student& s)
{
firstname = s.firstname;
surname = s.surname;
id_num = s.id_num;
age = s.age;
gpa = s.gpa;
count++;
}
Student::~Student() { count--; }
void Student::assignFName(string tempFName)
{
firstname = tempFName;
}
void Student::assignSName(string tempSName) { surname = tempSName; }
void Student::assignId(long Tid_num) { id_num = Tid_num; }
void Student::assignAge(int Tage) { age = Tage; }
void Student::assignGpa(float Tgpa) { gpa = Tgpa; }
string Student::getSName() { return surname; }
long Student::getId_num() { return id_num; }
int Student::getAge() { return age; }
float Student::getGpa() { return gpa; }
int Student::getNum() { return count; }
void Student::print() const
{
cout << firstname << " " << surname << " " << id_num << " " << age << " ";
cout << gpa << endl; // could do on same line, but do on next line just so can see that can be multiple lines, etc
}
int Student::count = 0;
Student.h:
#pragma once
//Module.h
#ifndef STD_H
#define STD_H
#include <string>
using namespace std;
class Student
{
public:
// just include one constructor definition here to show how it is written if do inline
Student(string fn = "nofirstname", string sn = "nosurname", long i = 0000, int a = 0, float s = 0)
:firstname(fn), surname(sn), id_num(i), age(a), gpa(s) {
count++;
}
Student(const Student& s);
~Student();
void assignFName(string tempFName);
void assignSName(string tempSName);
void assignId(long Tid_num);
void assignAge(int Tage);
void assignGpa(float Tgpa);
string getFName() { return firstname; } // just include one method here to show how it is written if do inline
string getSName();
long getId_num();
int getAge();
float getGpa();
void print() const;
static int getNum();
private:
string firstname, surname;
long id_num;
int age;
float gpa;
static int count;
};
#endif
queue.cpp:
#include "Queue.h"
#include "Student.h"
#include <iostream>
#include <stdlib.h>
void queue::enqueue(Student value) {
QueueNode* temp = new QueueNode(value); //allocating memory for the newly created node, with a value passed into it
if (tail == NULL) { //If there is no tail (i.e. only 1 block in the queue)...
head = tail = temp; //The tail and head are now the one block
return; //
} //
tail->next = temp; //The next address of the tail is made to equal the temporary node
tail = temp; //The tail becomes the temporary node
delete temp;
}
Student queue::dequeue() {
Student a;
if (head == tail) {//if only one node is there
head = tail = NULL;
} else {
head = head->next;
}
if (head == NULL) {
exit(1);
}
a = head->value;
return a;
//Student a;
//QueueNode* temp = head; //store the current head node of the queue
//delete (temp);
//if (head != NULL) {
// head = head->next;
//
//} else {
// tail = NULL;
// //return a;
//}
//a = head->value;
//return a;
}
void queue::printQueue() {
int count = 1; //initiazling counter variable as 1 so that the counter does not start at 0
while (head != NULL) //while the are still blocks in the queue
{
//cout << "\n\tBlock number " << count << " pushed: " << ; //print the block that was just inserted and what position it is at
head->value.print();
head = head->next; //equate the node to the next address
count++; //increment the counter
}
}
queue::~queue() {
head = tail = NULL;
}
queue::queue(const queue& q) {
QueueNode* hold = q.head;
QueueNode* temp, * oldtemp;
if (hold == q.tail)
{
temp = new QueueNode;
head = temp;
tail = temp;
}
else
{
temp = new QueueNode;
head = temp;
while (hold != q.tail)
{
// get the value at the node looking at on queue 'r' list
temp->value = hold->value;
// move to the next entry on 'r' list
hold = hold->next;
oldtemp = temp;
temp = new QueueNode;
oldtemp->next = temp;
}
tail = temp;
}
}
queue::queue() {
head = tail = NULL;
}
//queue::sizeOfQueue() { //function to return the number of nodes in the queue
// //takes in the pointer to the queue so that the function knows which queu to get the size of
// int size = 0; //intialize size integer to be returned
// while (node != NULL) { //for as long as a NULL node is not reached
// node = node->next; //equate the node to the next address
// size++; //increment the size integer
// } //eventually the node will reach the end of the queue where the next address is NULL (because there are no other nodes)
// return size; //return the integer for the size
//}
queue.h:
#pragma once
#include "Student.h"
#include "Node.h"
class queue {
public:
queue();
queue(const queue& q);
~queue();
void enqueue(Student value);
Student dequeue();
void printQueue();
private:
QueueNode* head;
QueueNode* tail;
};
Node.cpp:
#include "Queue.h"
#include "Node.h"
#include "Student.h"
#include <iostream>
QueueNode::QueueNode() {
value = Student();
next = NULL;
}
QueueNode::QueueNode(Student val) {
value = val;
next = NULL;
}
QueueNode::~QueueNode() {
value.~Student();
next = NULL;
}
Node.h:
#pragma once
#include "Student.h"
class QueueNode {
friend void enqueue(Student value);
friend void dequeue();
friend void printQueue();
public:
QueueNode* next; //PUBLIC VARIABLE
Student value;
QueueNode();
QueueNode(Student val);
~QueueNode();
private:
};
The input file that gets the details for the "Student" objects that go in the queue:
3
joe bloggs 40001 24 2.1
mary doe 40002 19 3.9
john boyd 40003 18 1

Show full line of a CSV file C++

I am making a program that reads a .CSV file and loads it into binary search trees to sort its content, since I managed to load the .CSV and implement the tree however the content of the file is:
1, Peter, 230151515
5, Merrick, 25551561
7, Lucky, 4301616199
2, luis, 2589191919
16, Alfredo, 25891919
8, Linda, 129616919
I am using the first data of each row as a key and with the code that I carry, it orders it correctly, however I want it to show the rest of the row, not just the key, someone could tell me how I could do that, to show all the data of each key ordered.
output:
1
2
5
7
8
16
What I want to print would be something like:
1 Peter 230151515
2 Luis 2589191919
5 Merrick 25551561
7 Lucky 4301616199
8 Linda 129616919
16 Alfredo 25891919
Someone to help me correct my mistake please.
#include <iostream>
#include <iomanip>
#include <fstream>
#include <string>
#include <sstream>
#include <vector>
#include<stdio.h>
#include<stdlib.h>
using namespace std;
struct node {
int key;
string name;
int num;
struct node *left, *right;
};
vector<node> persons;
struct node *newNode(int item)
{
struct node *temp = (struct node *)malloc(sizeof(struct node));
temp->key = item;
temp->left = temp->right = NULL;
return temp;
}
void inorder(struct node *root)
{
if (root != NULL)
{
//cout<<"\t";
inorder(root->left);
printf("\t%d\n", root->key);
inorder(root->right);
}
}
struct node* insert(struct node* node, int key)
{
/* If the tree is empty, return a new node */
if (node == NULL) return newNode(key);
/* Otherwise, recur down the tree */
if (key < node->key)
node->left = insert(node->left, key);
else if (key > node->key)
node->right = insert(node->right, key);
/* return the (unchanged) node pointer */
return node;
}
struct node * minValueNode(struct node* node)
{
struct node* current = node;
/* loop down to find the leftmost leaf */
while (current && current->left != NULL)
current = current->left;
return current;
}
int main()
{
struct node *root = NULL;
ifstream fin("data.txt");
if (!fin)
{
cout << "File not open\n";
return 1;
}
string line;
const char delim = ',';
while (getline(fin, line))
{
istringstream ss(line);
node person;
ss >> person.key; ss.ignore(10, delim);
getline(ss, person.name,delim);
ss >> person.num;
if (ss)
persons.push_back(person);
}
for (unsigned int i=0; i< persons.size(); i++)
{
cout << setw(5) << persons[i].key<< setw(20) << persons[i].name<< setw(15) << persons[i].num << '\n';
root = insert(root, persons[i].key);
insert(root, persons[i].key);
}
cout << "\n\nInorder:\n";
// cout<<node.name;
inorder(root);
/*/cout<<"\nDelete 50\n";
root = deleteNode(root, 50);
cout<<"Inorder traversal of the modified tree \n";
inorder(root);/*/
/*
insert(root, 80);*/
return 0;
}
When you are printing out the key, you can also print out the other information of each node. Here's a solution using cout:
void inorder(struct node *root)
{
if (root != NULL)
{
inorder(root->left);
std::cout << root->key << " " << root->name << " " << root->num << "\n";
inorder(root->right);
}
}
There were some main problems and some other problems. The main problems were that you didn't store and print all data. I did the following:
Clean up includes
Remove using namespace std;
Rename struct node to Node
Add a struct for Person next to the struct for Node
Add a constructor for Person to Node
Make insert a method
Use smart pointers. One problem of dynamic memory allocation is that you have to clean up but you didn't
#include <iostream>
#include <iomanip>
#include <fstream>
#include <memory>
#include <string>
#include <sstream>
#include <vector>
struct Person {
int key;
std::string name;
int num;
};
struct Node : Person {
Node(const Person &person) : Person(person) {}
std::unique_ptr<Node> left, right;
void insert(const Person &person);
};
void Node::insert(const Person &person) {
/* recur down the tree */
if (key > person.key) {
if (left)
left->insert(person);
else
left = std::make_unique<Node>(person);
} else if (key < person.key) {
if (right)
right->insert(person);
else
right = std::make_unique<Node>(person);
}
}
std::vector<Person> persons;
void inorder(Node *root) {
if (root) {
// cout<<"\t";
inorder(root->left.get());
std::cout << '\t' << root->key << ' ' << root->name << ' ' << root->num << '\n';
inorder(root->right.get());
}
}
Node *minValueNode(Node *node) {
Node *current = node;
/* loop down to find the leftmost leaf */
while (current && current->left) current = current->left.get();
return current;
}
int main() {
std::unique_ptr<Node> root;
std::ifstream fin("data.txt");
if (!fin) {
std::cout << "File not open\n";
return 1;
}
std::string line;
const char delim = ',';
while (std::getline(fin, line)) {
std::istringstream ss(line);
Person person;
ss >> person.key;
ss.ignore(10, delim);
std::getline(ss, person.name, delim);
ss >> person.num;
if (ss) persons.push_back(person);
}
for (unsigned int i = 0; i < persons.size(); i++) {
std::cout << std::setw(5) << persons[i].key << std::setw(20)
<< persons[i].name << std::setw(15) << persons[i].num << '\n';
if (!root) root = std::make_unique<Node>(persons[i]);
else root->insert(persons[i]);
}
std::cout << "\n\nInorder:\n";
// cout<<node.name;
inorder(root.get());
/*/cout<<"\nDelete 50\n";
root = deleteNode(root, 50);
cout<<"Inorder traversal of the modified tree \n";
inorder(root);/*/
/*
insert(root, 80);*/
return 0;
}

C++ Stack using a doubly linked list

I'm trying to implement a stack using a doubly linked list. I know that the functions for my stack class (push, pop) should contain calls to member functions of my doubly linked list class, but I'm having trouble actually implementing that.
dlist.cpp:
#include <iostream>
#include <fstream>
#include <string>
#include "dlist.hpp"
using namespace std;
void dlist::appendNodeFront(int shares, float pps){
Node *n = new Node(shares, pps);
if(front == NULL){
front = n;
back = n;
}
else {
front->prev = n;
n->next = front;
front = n;
}
}
void dlist::appendNodeBack(int shares, float pps){
Node *n = new Node(shares, pps);
if(back == NULL){
front = n;
back = n;
}
else {
back->next = n;
n->prev = back;
back = n;
}
}
void dlist::display(){
Node *temp = front;
cout << "List contents: ";
while(temp != NULL){
cout << temp->value << " ";
temp = temp->next;
}
cout << endl;
}
void dlist::display_reverse(){
Node *temp = back;
cout << "List contents in reverse: ";
while(temp != NULL){
cout << temp->value << " ";
temp = temp->prev;
}
cout << endl;
}
void dlist::destroyList(){
Node *T = back;
while(T != NULL){
Node *T2 = T;
T = T->prev;
delete T2;
}
front = NULL;
back = NULL;
}
stack.cpp:
#include <iostream>
#include <fstream>
#include <string>
#include "stack.hpp"
using namespace std;
stack::stack(){
int i;
for(i = 0; i < 1500; i++){
shares[i] = 0;
pps[i] = 0;
}
first = 0;
}
void stack::push(int num, float price){
if(first ==(1500-1)){
cout << "Stack is full" << endl;
return;
}
first++;
shares[first] = num;
pps[first] = price;
return;
}
void stack::pop(int *num, float *price){
if(first == -1){
cout << "Stack is empty" << endl;
return;
}
num = &shares[first];
price = &pps[first];
cout << shares[first] << endl;
cout << pps[first] << endl;
shares[first] = 0;
pps[first] = 0;
first--;
return;
}
Should the push function in stack basically be a call to appendNodeFront() or appendNodeback()? Any help or advice is greatly appreciated!
You can create a stack class, then use linked list class as its container. In a linked list class there is virtually no limit to the number of items, so you add artificial limit to make it work like a stack. In a linked list, items can be added/removed anywhere in the list, you can limit add/remove the tail node only to make it work like stack. The example below demonstrate the usage.
Node that this is purely a programming exercise. Stack is relatively primitive compared to Doubly-linked list. Encapsulating a linked-list inside stack has no advantage. Also note, I declared all members as public for the sake of simplifying the problem, you may want to change some members to protected/private
#include <iostream>
#include <fstream>
#include <string>
using std::cout;
class Node
{
public:
Node *prev;
Node *next;
int shares;
float pps;
Node(int vshares, float vpps)
{
shares = vshares;
pps = vpps;
prev = next = nullptr;
}
};
class dlist
{
public:
Node *head;
Node *tail;
dlist()
{
head = tail = nullptr;
}
~dlist()
{
destroy();
}
void push_back(int shares, float pps)
{
Node *node = new Node(shares, pps);
if (head == NULL)
{
head = tail = node;
}
else
{
tail->next = node;
node->prev = tail;
tail = node;
}
}
void destroy()
{
Node *walk = head;
while (walk)
{
Node *node = walk;
walk = walk->next;
delete node;
}
head = tail = nullptr;
}
};
class stack
{
public:
int maxsize;
int count;
dlist list;
stack(int size)
{
count = 0;
maxsize = size;
}
void push(int num, float price)
{
if (count < maxsize)
{
list.push_back(num, price);
count++;
}
}
void pop()
{
Node *tail = list.tail;
if (!tail)
{
//already empty
return;
}
if (tail == list.head)
{
//only one element in the list
delete tail;
list.head = list.tail = nullptr;
count--;
}
else
{
Node *temp = list.tail->prev;
delete list.tail;
list.tail = temp;
list.tail->next = nullptr;
count--;
}
}
void display()
{
Node *walk = list.head;
while (walk)
{
cout << "(" << walk->shares << "," << walk->pps << ") ";
walk = walk->next;
}
cout << "\n";
}
};
int main()
{
stack s(3);
s.push(101, 0.25f);
s.push(102, 0.25f);
s.push(103, 0.25f);
s.push(104, 0.25f);
s.display();
s.pop();
s.display();
return 0;
}

Linked list class

The purpose of my program is to read in data from a file and build a linked list with this data and then deallocate all the nodes used.
the program also needs to print out the address of nodes after they are created and then after that they are deleted
#include <iostream>
#include <string>
#include <fstream>
#include "BigHero.h"
using namespace std;
// Linked List Struct
struct Node{
BigHero data;
Node* Next;
};
// Funtion Prototypes
int countHeros(string,int&);
void createList(BigHero,int,Node*&,Node*&,Node*&);
void printList(Node*,Node*,Node*);
void deallocateList(Node*&,Node*&,Node*&);
int main()
{
// Program Variables
Node* head;
Node* currentPtr;
Node* newNodePtr;
string Filename = "ola5party.dat"; // File string varible
int charNumber = 0; // variable to hold number of Heroes
int i = 0; // Loop control varible
countHeros(Filename,charNumber); // Function call used to count number of Heros
ifstream inFile;
inFile.open(Filename.c_str());
if(!inFile){
cout << "Error in opening file" << endl;
return 0;
}
BigHero Hero;
while(inFile)
{
inFile >> Hero;
createList(Hero,charNumber,head,currentPtr,newNodePtr);
}
printList(head,currentPtr,newNodePtr);
deallocateList(head,currentPtr,newNodePtr);
inFile.close();
return 0;
}
int countHeros(string Filename,int& charNumber)
{
ifstream inFile;
inFile.open(Filename.c_str());
string aLineStr;
while (getline(inFile, aLineStr))
{
if (!aLineStr.empty())
charNumber++;
}
inFile.close();
return charNumber;
}
void createList(BigHero Hero, int charNumber,Node*& head, Node*& currentPtr, Node*& newNodePtr)
{
head = new Node;
head->data =Hero;
currentPtr = head;
newNodePtr = new Node;
cout << "Allocated # " << newNodePtr << endl;
newNodePtr->data = Hero;
currentPtr->Next = newNodePtr;
currentPtr = newNodePtr;
}
void printList(Node* head, Node* currentPtr, Node* newNodePtr)
{
if(head != NULL)
{
currentPtr = head;
while(currentPtr->Next != NULL)
{
cout << currentPtr->data << endl;
currentPtr = currentPtr->Next;
}
}
}
void deallocateList(Node*& head ,Node*& currentPtr,Node*& newNodePtr)
{
if( head != NULL)
{
currentPtr = head;
while( head -> Next != NULL)
{
head = head->Next;
cout << "Deleting # " << head << endl;
delete currentPtr;
currentPtr = head;
}
delete head;
head = NULL;
currentPtr = NULL;
}
}
the program like this runs without errors, but here is the problem it will input all the information required but since i only have one variable hero class it is constantly replacing the information.
i tried to make a class array (example hero[i]) but cant seem to get it right and am not even sure if that is the solution. Everything is fine but i cant get the desired number of class object and i always end up with one class
this is my desired output but i only get one class object
Allocated#0x8722178
Allocated#0x87221d0
Allocated#0x8722210
Allocated#0x8722230
Allocated#0x8722288
Allocated#0x87222c8
Hero:MacWarrior­Level134,(34,16,48)­Exp:13425
Hero:LinuxMage­Level149,(24,54,21)­Exp:14926
Hero:PCBard­Level122,(18,32,17)­Exp:12221
Hero:PythonThief­Level90,(24,18,61)­Exp:9001
Hero:CplusPaladin­Level159,(31,38,29)­Exp:15925
Deleting#0x8722178
Deleting#0x87221d0
Deleting#0x8722210
Deleting#0x8722230
Deleting#0x8722288
Deleting#0x87222c8
It seems you have misunderstood the basic idea behind a link listed. You are not supposed to overwrite head again and again when adding element. head shall only be changed when the list is empty.
Try something like this:
struct Node
{
BigHero data;
Node* next;
};
void addNewNode(Node*& head, ....)
{
if (head == nullptr)
{
// List empty so add new node as head
head = new Node;
head->next = nullptr;
return;
}
// Find last element in list (performance can be improved with a tail*)
Node* temp = head;
while (temp->next != nullptr) temp = temp->next;
// Add new element to end of list
temp->next = new Node;
temp->next->next = nullptr
return;
}
int main()
{
Node* head = nullptr;
addNewNode(head, ....);
return 0;
}
For performance it is often good to have a tail-pointer also.
Further you should not define head in main() but make a class/struct for it and put the relevant functions in the class. Like:
struct Node
{
BigHero data;
Node* next;
};
class ListOfNode
{
public:
ListOfNode() : head(nullptr), size(0) {}
~ListOfNode()
{
// Delete all nodes
}
void addNewNode(....)
{
// ....
++size;
}
size_t size() { return size; }
private:
Node* head; // Optional: Add a tail* for better performance
size_t size;
};
int main()
{
ListOfNode list;
list.addNewNode(....);
cout << list.size() << endl;
return 0;
}

How to read from file in C++ into a queue to make postfix evaluation?

I am new to C++. I am trying to do an exercise where I supposed to read postfix operations into a queue and then evaluate it using stack. In my file every line includes only one postfix operation and all operations thus lines ends with #. But I couldn't make the reading part. My function for that only does it job for 2 times but it needs to do 3 times.
Here is what I managed to write so far:
//queue cpp file
#include<iostream>
#include <cassert>
#include "Queue.h"
#include "stdlib.h"
using namespace std;
Queue::Queue(){
Size = 0;
head = NULL;
rear = NULL;
}
Queue::~Queue(){
Node* curPtr = head;
while( curPtr != 0 ) {
Node* nex = curPtr->next;
delete curPtr;
curPtr = nex;
}
head = 0;
}
bool Queue::empty() const {
if(Size==0){
return true;
}
return false;
}
int Queue::size() const {
return Size;
}
void Queue::enqueue(ElementType x){
Node *newNode = new Node;
newNode->data = x;
if(Size == 0){
rear=head = newNode;
Size++;
}
else{
rear->next=newNode;
rear=rear->next;
Size++;
}
}
void Queue::dequeue(){
Node * newNode;
if(Size==1){
newNode=head;
rear=NULL;
head=NULL;
delete newNode;
}
else{
newNode=head;
head=head->next;
delete newNode;
}
Size--;
}
ElementType Queue::front(){
return head->data;
}
//queue .h file
#ifndef QUEUE
#define QUEUE
using namespace std;
typedef string ElementType; // type of item to be stored
class Queue{
public:
int size() const; //return the number of elements in the queue
bool empty() const; //return true if queue is empty, else return false
void enqueue(ElementType x); //add x to the queue, increasing size()
void dequeue(); //remove the element most recently added to the queue, decreasing size()
ElementType front(); //return the element most recently added to the queue
Queue();
~Queue();
private:
class Node{
public:
ElementType data;
Node * next;
};
Node * head;
Node * rear;
int Size;
};
#endif
// stack cpp file
#include<iostream>
#include <cassert>
#include "Stack.h"
#include "stdlib.h"
using namespace std;
Stack::Stack(){
Size = 0;
head = NULL;
}
Stack::~Stack(){
cout << "destructor called2" <<endl;
Node* deleter;
deleter=head;
Node* temp;
while(deleter!=NULL){
temp=deleter;
deleter=deleter->next;
delete temp;
}
}
bool Stack::empty() const {
if(Size==0){
return true;
}
return false;
}
int Stack::size() const {
return Size;
}
void Stack::push(ItemType x){
Node *newNode = new Node;
newNode->data = x;
if(Size == 0){
head = newNode;
Size++;
}
else{
newNode->next = head;
head = newNode;
Size++;
}
}
void Stack::pop(){
Node *newNode;
if(Size==1){
newNode=head;
head=NULL;
delete newNode;
}
else{
newNode=head;
head=head->next;
delete newNode;
}
Size--;
}
ItemType Stack::top(){
return head->data;
}
// stack .h file
#ifndef STACK
#define STACK
#include<iostream>
using namespace std;
typedef int ItemType; // type of item to be stored
class Stack{
public:
Stack();
~Stack();
int size() const; //return the number of elements in the stack
bool empty() const; //return true if stack is empty, else return false
void push(ItemType x); //add x to the stack, increasing size()
void pop(); //remove the element most recently added to the stack, decreasing size()
ItemType top(); //return the element most recently added to the stack
private:
class Node{
public:
ItemType data;
Node * next;
};
Node * head;
int Size;
};
#endif
//test .cpp file where operations happen and main is
#include "Stack.h"
#include "Queue.h"
#include <stdio.h>
#include <iostream>
#include <string>
#include <sstream>
#include <fstream>
using namespace std;
void operatorAndWriter(Queue& k, Stack &l, ofstream &myfile);
void reader(Queue &loko, Stack &l);
int main(){
Stack l;
Queue at;
reader(at, l);
return 0;
}
void reader(Queue &loko, Stack &l){
cout << "Enter the file name : " << endl;
string filename;
cin >> filename;
ifstream meinfile (filename);
string line;
string sub;
ofstream myfile("example.txt");
while (! meinfile.eof()){
getline (meinfile, line);
istringstream iss(line);
while (iss >> sub){
loko.enqueue(sub);
}
operatorAndWriter(loko, l, myfile);
meinfile.close();
}
myfile.close();
}
void operatorAndWriter(Queue &k, Stack &l, ofstream &myfile){
if(myfile.is_open()){
while (k.size()!=0){
string op = k.front();
if (op == "+"){
int a = l.top();
l.pop();
int b = l.top();
l.pop();
l.push(a+b);
myfile << "+ ";
}
else if (op == "-"){
int a = l.top();
l.pop();
int b = l.top();
l.pop();
l.push(b-a);
myfile << "- ";
}
else if (op == "*"){
int a = l.top();
l.pop();
int b = l.top();
l.pop();
l.push(a*b);
myfile << "* ";
}
else if (op == "#"){
myfile << "# " ;
myfile << l.top() << endl;
l.pop();
}
else{
int y;
y=atoi(op.c_str());
l.push(y);
myfile <<l.top()<<" ";
}
k.dequeue();
}
}
}
// here is the input file
23 4 * 19 2 - + #
6 3 - #
36 #
// here is my example file which i tried create and write operations and their solutions in it. however there is just one solution which belongs to the first sentence of the a.txt file.
23 4 * 19 2 - + # 109
This is really a lot of code. First some stylistic advice:
Use nullptr instead of NULL.
2. you should check if the File actually exists so you don't corrupt your memory by accident.
3. Simplify your code, and only post the important part.
4. Include guards should end with _H
Now to your problem:
I didn't read all of your code but first of all you can simplify your reading function by writing something like this:
ifstream meinfile ("input.txt",ios::in);
while (getline (meinfile,line)){
// Use line here
}
I don't know if this will help, but is a lot of code after all.