Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
I'm writing a function to find all occurrences of a node in a linked list, the function will return the number of occurrences to the main function which will then display those occurrences. The program does compile but the it just freezes and nothing seems to happen when I enter the correct name to look for, if I enter the wrong name, which is not in the list, the findall function returns 0 and the rest of the program works fine. Please take a look.
main.cpp
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
#include "List.h"
void extra(list &);
/***********************************
* Main
* Test function - DO NOT CHANGE
***********************************/
void main()
{
list a;
extra(a);
}
/***********************************
* Extra Credit
* Test function - DO NOT CHANGE
***********************************/
void extra(list &a)
{ int i,n;
node_ptr map[4];
string first,last;
// Find node
cout << endl;
cout << "Enter First and Last name: ";
cin >> first >> last;
n = a.findall(first,last,map,4);
// Display forwards
cout << endl;
cout << "Find List\n--------------\n";
for (i = 0; i < n; i++)
{
map[i]->put(cout);
}
}
List.h
#include "Node.h"
#include <iostream>
#include <string>
using namespace std;
class list
{ public:
list(); // Empty constructor
~list(); // Destructor
int findall(string, string, node_ptr*, int);
node *find(string, string); // Locate a note
private:
node *head;
};
Node.h
#include <iostream>
#include <string>
using namespace std;
class list;
class node
{ friend list;
public:
node(); // Null constructor
~node(); // Destructor
void put(ostream &out); // Put
private:
string first,last;
int age;
node *next;
};
typedef node * node_ptr;
List.cpp
#include "List.h"
#include <iostream>
#include <string>
using namespace std;
/**
* Empty Constructor
*
*/
list::list()
{
head = nullptr;
}
/**
* Destructor Constructor
*
*/
list::~list()
{ if (head == nullptr) return;
node *p = head, *t;
while (p)
{
t = p;
p = p->next;
delete t;
}
head = nullptr;
}
/**
* Locate node
*
*/
node *list::find(string last, string first)
{
node *temp = head;
while (temp)
{
if (temp->first == first && temp->last == last) return temp;
temp = temp->next;
}
return nullptr;
}
/**
* Find all.
*
*/
int list::findall(string first, string last, node_ptr* map, int n)
{
int ans;
ans = 0;
*map = find(first, last);
while (*map != NULL)
{
ans++;
*map = (*map)->next;
*map = find(first, last);
}
return ans;
}
Node.cpp
#include "Node.h"
#include <iostream>
#include <string>
#include <iomanip>
using namespace std;
/**
* Empty Constructor
*
*/
node::node()
{
last = "";
first = "";
age = 0;
next = nullptr;
}
/**
* Destructor
*
*/
node::~node()
{ if (next != nullptr) next = nullptr;
}
/**
* Put
*
*/
void node::put(ostream &out)
{ out << setw(14) << left << last << setw(14) << first << setw(10) << age << endl;
}
I really appreciate your help. Thank you.
findall() freezes because it gets stuck in an endless loop.
If no matching node is found, the first call to find() returns nullptr and findall() exits.
But if a matching node is found, a loop is entered, calling find() to search the entire list all over again from the beginning. That will find the same node as before. Then you call find() again, and again, and so on.
To solve this issue, if find() returns a matching node, you need to pass the next node in the following call to find() so it can start searching where the previous search left off. Repeat until you reach the end of the list.
class list
{ public:
...
int findall(string first, string last, node_ptr *map, int n);
node_ptr find(string first, string last, node_ptr start = nullptr); // Locate a note
...
};
node_ptr list::find(string last, string first, node_ptr start)
{
node_ptr temp = (start) ? start : head;
while (temp)
{
if ((temp->first == first) && (temp->last == last)) break;
temp = temp->next;
}
return temp;
}
int list::findall(string first, string last, node_ptr* map, int n)
{
int ans = 0;
node_ptr temp = nullptr;
while (ans < n)
{
temp = find(first, last, temp);
if (!temp) break;
*map++ = temp;
++ans;
temp = temp->next;
}
return ans;
}
Update: if you are not able to change the signature of find() then you will have to re-write findall() to duplicate what find() does:
class list
{ public:
...
int findall(string first, string last, node_ptr *map, int n);
node_ptr find(string first, string last); // Locate a node
...
};
node_ptr list::find(string last, string first)
{
node_ptr temp = head;
while (temp)
{
if ((temp->first == first) && (temp->last == last)) break;
temp = temp->next;
}
return temp;
}
int list::findall(string first, string last, node_ptr* map, int n)
{
int ans = 0;
node_ptr temp = head;
while (ans < n)
{
while (temp)
{
if ((temp->first == first) && (temp->last == last)) break;
temp = temp->next;
}
if (!temp) break;
*map++ = temp;
++ans;
temp = temp->next;
}
return ans;
}
Related
I am tasked with implementing a new class function called bool List::largest_value(int &largest) within a given class List. The instruction is:
If the list is not empty, put the largest value in the largest
parameter and return true. If the list is empty, return false.
My question is, how do I find the largest value within a parameter?
Here is what I have so far for bool List::largest_value(int &largest):
// Fill in the functions at the bottom of this file
//
#include <iostream>
#include <climits>
using namespace std;
#include "list.h"
// on some machines member variables are not automatically initialized to 0
List::List()
{
m_head = NULL;
}
// delete all Nodes in the list
// since they are dynamically allocated using new, they won't go away
// automatically when the list is deleted
// Rule of thumb: destructor deletes all memory created by member functions
List::~List()
{
while (m_head)
{
Node *tmp = m_head;
m_head = m_head->m_next;
delete tmp;
}
}
// always insert at the front of the list
// Note: this works even in the SPECIAL CASE that the list is empty
void List::insert(int value)
{
m_head = new Node(value, m_head);
}
// iterate through all the Nodes in the list and print each Node
void List::print()
{
for (Node *ptr = m_head; ptr; ptr = ptr->m_next)
{
cout << ptr->m_value << endl;
}
}
void List::compare(int target, int &less_than, int &equal, int &greater_than)
{
Node *temp = m_head;
less_than = 0;
equal = 0;
greater_than = 0;
while(temp != NULL)
{
if(temp->m_value > target)
{
greater_than++;
}
else if(temp->m_value < target)
{
less_than++;
}
else if(temp->m_value == target)
{
equal++;
}
temp = temp-> m_next;
}
}
bool List::largest_value(int &largest)
{
Node *temp = m_head;
largest = INT_MIN;
if(temp == NULL)
{
return false;
}
while(temp != NULL)
{
if(temp->m_value > largest)
{
largest = temp->m_value;
}
temp = temp->m_next;
}
return true;
}
Here is the given class List:
class List
{
public:
List();
~List();
void insert(int value); // insert at beginning of list
void print(); // print all values in the list
void compare(int target, int &less_than, int &equal, int &greater_than);
bool largest_value(int &largest);
private:
class Node
{
public:
Node(int value, Node *next)
{m_value = value; m_next = next;}
int m_value;
Node *m_next;
};
Node *m_head;
};
Main.cpp:
#include <iostream>
using namespace std;
#include "list.h"
int main()
{
List list;
int value;
// read values and insert them into list
while (cin >> value)
{
list.insert(value);
}
int largest;
bool result = list.largest_value(largest);
if (result == false)
{
cout << "empty list" << endl;
return 1;
}
else
{
cout << "The largest value you entered is: " << largest << endl;
}
}
My code compiles and runs, however I keep receiving the output empty list. I honestly have no idea what I need to change in my bool List::largest_value(int &largest)function. I am still very new to linked lists. Any help would be appreciated
For an assignment i have to build this. I just can't seem to see what i am doing wrong. When I am trying to run this code I keep seeing the pointer that my linked list stores it's starting location get pointed to garbage right in the middle. I don't know if Visual Studio is just hazing me or if I am miss assigning a pointer somewhere.
This is the main class i use to run my code
#include "stdafx.h"
#include "Iterator.h"
#include "Node.h"
#include "List.h"
#include <iostream>
int main()
{
int input = 0;
List<double> salaryList;
std::cin >> input;
Node<double> tim(7.0, nullptr);
Node<double> sim(input, nullptr);
Node<double> jim(7.5, nullptr);
salaryList.Add_back(&jim);
salaryList.Add_back(&tim);
salaryList.Insert_front(&sim);
Iterator<double> checkSalaries=salaryList.begin();
//std::cout << "printing all elements in Iterator" << std::endl;
while (checkSalaries.Is_item()){
double x = (*checkSalaries).value;
std::cout << x << std::endl;
checkSalaries++;
}
system("PAUSE");
return 0;
}
This is the code for the LinkedList, i just named it List :
#include "Iterator.h"
#include "Node.h"
template <class t>
class List
{
private:
Node<t>* start=nullptr;
Node<t>* end=nullptr;
int size = 0;
public:
List() {
start = nullptr;
end = nullptr;
}
~List() {
}
void Insert_front(Node<t> * input) {
if (start != nullptr)
{
input->setPoint(start);
start = input;
size++;
}
else {
start = input;
}
if (start->point != nullptr && end == nullptr) {
end = start->point;
size++;
}
}
void Add_back(Node<t> * input) {
if (end != nullptr) {
Node<t> temp = (*end);
temp.setPoint(input);
end = input;
}
else {
if (start != nullptr) {
start->point=input;
end = input;
}
else {
start = input;
}
size++;
}
}
Iterator<t> begin() const
{
Node<t> tempNode = *start;
Iterator<t> temp(&tempNode);
return temp;
}
void Remove_all()
{
List<Node<t>> temp;
start = temp.start;
end = temp.end;
size = 0;
}
int Size() const {
return size;
}
};
This is the Node code:
template <class T>
class Node {
public:
T value;
Node<T> * point;
Node(T first, Node<T> * second)
{
value = first;
point = second;
}
Node()
{
value = NULL;
point = nullptr;
}
void setPoint(Node<T> * input) {
point = input;
}
};
I am going to include here two images the first is what it looks like just before it goes bad, and the next is what happens right after, it seems to occur fairly at random but i have found that using cout always triggers it so i commented out that line, though that didn't resolve the issue.
Good StateBad State
On my first review, it seems the local variable in begin method is creating the issue. Please check my code below. I have commented out the temporary variable created in the begin method and instead made use of the pointer start. This should solve the issue.
Iterator<t> begin() const
{
// Node<t> tempNode = *start; <-- A local variable is used here
// Iterator<t> temp(&tempNode); <-- address of local variable passed to iterator.
Iterator<t> temp(start);
return temp;
}
#include<iostream>
#include<stdlib.h>
#include<conio.h>
#include <ctime>
#include <fstream>
#include <windows.h>
#include <string>
using namespace std;
/* data variable is used to store data as name
suggests,the "next" is a pointer of the type node
that is used to point to the next node of the
Linked List*/
/*
* Node Declaration
*/
struct node
{
string info;
struct node *next;
}*start;
/*
* Class Declaration
*/
class single_llist
{
public:
node* create_node(string);
void insert_begin();
void insert_pos();
void insert_last();
void delete_pos();
void sort();
void search();
void update();
void reverse();
void display();
single_llist()
{
start = NULL;
}
};
/*
* Inserting element in beginning
*/
void single_llist::insert_begin()
{
string value;
cout<<"Enter the value to be inserted: ";
cin>>value;
struct node *temp, *p;
temp = create_node(value);
if (start == NULL)
{
start = temp;
start->next = NULL;
}
else
{
p = start;
start = temp;
start->next = p;
}
cout<<"Element Inserted at beginning"<<endl;
}
I'm developing my program with Dev C ++ program.I trying to entering specific words to txt file and save them.Therefore I'm dealing with string.The program gives this error: undefined reference to single_llist::create_node(std::string) and showing me that there is mistake here, temp = create_node(value);I still researching what I need to do for solving this problem?
Thanks for #NathanOliver I think I tried to wrong way without creating node first.For creating node check following code fragment.
/*
* Creating Node
*/
node *single_llist::create_node(string value)
{
struct node *temp, *s;
temp = new(struct node);
if (temp == NULL)
{
cout<<"Memory not allocated "<<endl;
return 0;
}
else
{
temp->info = value;
temp->next = NULL;
return temp;
}
}
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.
Im reading strings from a file and inserting them into a LinkedList in alphabetical order (C++). I have made the node and list classes but something is wrong with them. I have done this in Java and it works 100% without any problems. This leads me to believe that I must have messed up with pointers somewhere. This is also only the second time I use the '->' symbol. So I may have used it erroneously somewhere. Some helpful tips are appreciated. Thanks in advance.
//NODE CLASS
#include <string>
#include <iostream>
using namespace std;
class Node {
string word;
int count;
Node* next;
public:
Node (string aWord) {
word = aWord;
count = 1;
}
Node (string aWord, Node* theNext) {
word = aWord;
next = theNext;
}
void increaseCount() {
count++;
}
string getWord() {
return word;
}
int getCount() {
return count;
}
Node* getNext() {
return next;
}
void setNext(Node* theNext) {
next = theNext;
}
};
//LIST CLASS
#include<iostream>
using namespace std;
class LinkedList {
Node* head;
public:
LinkedList() {
head = new Node(" ");
}
void insert(string word) {
Node* temp = head;
Node* previous = head;
while (temp != NULL && temp->getWord() < word) {
previous = temp;
temp = temp->getNext();
}
if (temp == NULL) {
Node* node= new Node(word);
previous-> setNext(node);
} else {
if (temp-> getWord() == word) {
temp->increaseCount();
} else if (temp->getWord() > word) {
Node* node = new Node(word, temp);
previous->setNext(node);
}
}
}
void print() {
Node* temp = head->getNext();
while (temp != NULL) {
cout<< temp;
temp=temp->getNext();
}
}
};
//MAIN
#include <iostream>
#include <iostream>
#include <fstream>
#include "Node.h"
#include "LinkedList.h"
using namespace std;
int main(int argc, const char * argv[]) {
ifstream inFile("WordsStatisticData1.txt");
if (!inFile.is_open())
cout<< "Could not open the file"<< endl;
else {
string readData;
LinkedList list = *new LinkedList(); //Probably a problem here
while (inFile >> readData) {
list.insert(readData);
inFile.close();
list.print();
}
}
}
I may be declaring things totally wrong within the main as well.
My output looks like an address '0x' with random characters.
You're printing out temp where temp is a Node*. A pointer is just the address of an object, hence why you're getting an address in your output.
Seems like you want to get the string that the Node contains. If so, you want:
cout << temp->getWord();
Another problem you have is that you close your file and print the list inside the loop, which means it'll happen right after the first word has been read. You probably mean to do this after the loop, so all of the words in the file can be read.
You also have problem with the line you marked as such. Using the new keyword will dynamically allocate an object. These objects need to be later deleted with delete. However, you dereference the dynamically allocated object (with *) and copy it, losing any reference to the dynamically allocated object - this is a classic memory leak. The dynamic allocation here is completely unnecessary. Just do:
LinkedList list;