I have a this Tree Class:
#include <fstream>
using namespace std;
#ifndef HUFF_TREE_H
#define HUFF_TREE_H
class HuffTree{
public:
HuffTree();
HuffTree(char data, float frequency);
~HuffTree();
HuffTree& operator = (const HuffTree& tree);
int getNumberNodes();
float getFrequency();
void merge(HuffTree *tree);
friend ostream& operator << (ostream &out, const HuffTree &tree);
private:
struct node{
char data;
float frequency;
node* left;
node* right;
};
node* head;
int number_nodes;
float avg_code_length;
void destroy(node* &head);
void copyTree(node* &t1, node* t2);
};
#endif
Here is the code for the overloaded output operator:
ostream& operator << (ostream &out, const HuffTree &tree){
out << "testing";
return out;
}
In my main function, I call function as follows:
HuffTree* tree;
cout << tree;
From what I have read, this should work, but I am getting hexadecimal numbers printed to the screen. The above example prints out "0x1dcc2b0". The same thing happens if I pass it a file handle. I think I just need a fresh pair of eyes here, can anyone see my problem?
Since tree is a pointer, you're outputting a pointer.
Instead, you want to do this:
cout << *tree
Related
I recently asked the question: Is ostream& operator<< better practice in a class than using std::cout? and got an excellent answer.
When I tried to implement the solution I got errors:
no operator "<<" matches these operands
and
binary '<<': no operator found which takes a right-hand operand of type 'LinkedList' (or there is no acceptable conversion)
The simplest solution in this case would be to add a std::ostream parameter to your display() method, eg:
LinkedList.h
#include <iostream>
#pragma once
class LinkedList
{
struct Node {
int data = 0;
Node* prev = nullptr;
Node* next = nullptr;
};
private:
Node* m_head;
public:
// CONSTRUCTOR
LinkedList();
// DESTRUCTOR
~LinkedList();
void display(std::ostream& out) const;
};
LinkedList.cpp
#include <iostream>
#include "LinkedList.h"
LinkedList::LinkedList() {
m_head = nullptr;
}
void LinkedList::display(std::ostream &out) const {
Node* curr = m_head;
while (curr) {
out << curr->data << " -> ";
curr = curr->next;
}
out << std::endl;
}
std::ostream& operator<<(std::ostream &out, const LinkedList &list) {
list.display(out);
return out;
}
Main.cpp (generates error)
#include <iostream>
#include "LinkedList.h"
int main() {
LinkedList list;
std::cout << list;
}
I got some help with this question but it was swiftly deleted...
Essentially the problem is that std::ostream& operator<<(std::ostream &out, const LinkedList &list) is not correctly advertised.
We need to add friend std::ostream& operator<<(std::ostream& output, const SortedList& list); to the LinkedList.h file within the LinkedList class
LinkedList.h
#include <iostream>
#pragma once
class LinkedList
{
struct Node {
int data = 0;
Node* next = nullptr;
};
private:
Node* m_head;
public:
// CONSTRUCTOR
LinkedList();
// DESTRUCTOR
~LinkedList();
void display(std::ostream& out) const;
friend std::ostream& operator<<(std::ostream& output, const LinkedList& list);
};
This is a continuation of my last post. I'm getting this error now:
Error C2679 binary '<<': no operator found which takes a right-hand operand of type 'T'
This is happening because of a friend operator overload function not understanding the type T being overloaded for some reason.
#include <iostream>
#include <fstream>
#include <string>
template <typename T>
class LL
{
struct Node
{
T mData;
Node *mNext;
Node();
Node(T data);
};
private:
Node *mHead, *mTail;
int mCount;
public:
LL();
~LL();
bool insert(T data);
bool isExist(T data);
bool remove(T data);
void showLinkedList();
void clear();
int getCount() const;
bool isEmpty();
friend std::ofstream& operator<<(std::ofstream& output, const LL& obj)
{
Node* tmp;
if (obj.mHead != NULL)
{
tmp = obj.mHead;
while (tmp != NULL)
{
output << tmp->mData << std::endl; // "tmp->mData" is where the error is
tmp = tmp->mNext;
}
}
return output;
}
};
Your stream operator should be defined with std::ostream not std::ofstream, e.g.:
friend std::ostream& operator<<(std::ostream& output, const LL& obj)
I am trying to make a Linked List Container LLC and overload the << operator as a friend. It seems like no mater what I do it either prints the memory address or throws a segmentation fault. I dont totally understand c++ yet so it is probably something obvious.
in LLC.cpp
ostream& operator<<(ostream& os, const LLC* list){
Node *curr = list.first;
for(curr; curr != NULL; curr= curr -> next){
os << curr -> data << "\n";
}
return os;
}
int main(int argc, char *argv[]){
string arr [] = {"a","b","c","d","e","f"};
LLC* link = new LLC(arr);
cout<<"testing: ";
cout<<(link);
}
in LLC.h
struct Node {
std::string data;
Node *next;
};
class LLC {
private:
Node *first;
Node *last;
public:
int main(int argc, char *argv[]);
LLC(){
first=NULL;
last=NULL;
}
friend std::ostream& operator<<(std::ostream& os, const LLC*);
std::ostream already has an operator<< that takes a pointer (via void*) as input. That is why you get hex output. Your operator<< overload should be taking in the LLC object by const reference, not by const pointer, to avoid ambiguities.
You did not post enough code to demonstrate the segfault error, but I suspect it is because you are not managing your node instances correctly inside the list, so when your operator<< tries to access them, it encounters a bad pointer along the way and crashes.
Try something more like this:
LLC.h
#ifndef LLCH
#define LLCH
#include <iostream>
#include <string>
struct Node {
std::string data;
Node *next;
Node(const std::string& d);
};
class LLC {
private:
Node *first;
Node *last;
public:
LLC();
template<size_t N>
LLC(std::string (&arr)[N])
: first(NULL), last(NULL) {
for(size_t i = 0; i < N; ++i) {
addToBack(arr[i]);
}
}
// other constructors, destructor, etc...
void addToBack(const std::string &s);
// other methods ...
friend std::ostream& operator<<(std::ostream& os, const LLC& list);
// other operators ...
};
#endif
LLC.cpp
#include "LLC.h"
Node::Node(const std::string& d)
: data(d), next(NULL) {
}
LLC::LLC()
: first(NULL), last(NULL) {
}
// other constructors, destructor, etc...
void LLC::addToBack(const std::string &s) {
Node *n = new Node(s);
if (!first) first = n;
if (last) last->next = n;
last = n;
}
// other methods ...
std::ostream& operator<<(std::ostream& os, const LLC& list) {
for(Node *curr = list.first; curr != NULL; curr = curr->next) {
os << curr->data << "\n";
}
return os;
}
// other operators ...
Main.cpp
#include <iostream>
#include <string>
#include "LLC.h"
int main(int argc, char *argv[]) {
std::string arr[] = {"a", "b", "c", "d", "e", "f"};
LLC* link = new LLC(arr);
cout << "testing: " << *link;
delete link;
/* or simply:
LLC link(arr);
cout << "testing: " << link;
*/
return 0;
}
I would like to save my binary tree to txt file. Here's what I have
qt.h
#ifndef QT_H_INCLUDED
#define QT_H_INCLUDED
#include<iostream>
using namespace std;
template<typename T>
class Node{
T data;
Node<T> *left;
Node<T> *right;
public:
Node(T d) : data(d), left(nullptr), right(nullptr){}
void print(){
cout << data << endl;}
T getData()const {
return data;
}
void setData(const T &value){
data = value;
}
template<typename X> friend class Tree;
template<T> friend ostream& operator<<(ostream &os, Node &n);
};
template<typename T>
ostream& operator<<(ostream &os, Node<T> &n){
os << n->data;
return os;
}
#endif // QT_H_INCLUDED
then tree.h
#ifndef TREE_H_INCLUDED
#define TREE_H_INCLUDED
#include "qt.h"
#include <fstream>
#include <iostream>
namespace std;
template<typename T>
class Tree{
Node<T> *root;
void insertIntoTree(T &d, Node<T> *&r);
void printTree(Node<T> *r);
void deleteTree(Node<T> *&r);
Node<T>* findInTree(T &d, Node<T> *r, Node<T> *&parent);
void deleteLeaf(Node<T> *p, Node<T> *q);
void deleteInBranch(Node<T> *p, Node<T> *g);
void zapisDoSouboru(Node<T> *r);
public:
Tree() : root(nullptr){}
~Tree(){
clean();
}
bool find(T d){
Node<T> *dummy=nullptr;
return findInTree(d, root, dummy);
};
void clean(){
deleteTree(root);}
void insert(T d){
insertIntoTree(d, root);}
void print(){
printTree(root);
}
bool deleteNode(T d);
void zapis(){
zapisDoSouboru(root);
}
}
template<typename T>
void Tree<T>::zapisDoSouboru(Node<T> *r){
fstream f;
f.open("mytext.txt", ios_base::app);
if(r){
f << r;
}
f.close();
zapisDoSouboru(r->left);
zapisDoSouboru(r->right);
}
the idea was to overload operator<< for Node and then use recursion in zapisDoSouboru and save it Node by Node. Unfortunately it does not work.
Does anybody know, where the problem is?
Thank you for helping
EDIT
in
class Tree{
void zapis(ostream& f, Node<T> *r);
public:
void zapisDoSouboru(){
fstream f;
f.open("mytext.txt", ios_base::app);
zapis(f, root);
f.close();
}
}
template<typename T>
void Tree<T>::zapis(ostream& f,Node<T> *r){
if(r){
zapis(f, r->left);
f << r;
zapis(f, r->right);
}
}
I changed the whole recursion, but now it looks like it works, but it doesnt write anything in the file. Isnt the reference to f wrong? The file opens and close, zapis() goes through all nodes.
In the function zapisDoSouboru you need to check if the child nodes are nullptr otherwise it will segfault whenever it reaches the leaf nodes.
Here is the modified version:
template
void Tree<T>::zapisDoSouboru(Node<T> *r){
fstream f;
f.open("mytext.txt", ios_base::app);
if(r){
f << r;
}
f.close();
if(nullptr != r->left) {
zapisDoSouboru(r->left);
}
if(nullptr != r->right) {
zapisDoSouboru(r->right);
}
}
Also the operator you have defined for node it is not being picked up by the compiler.
This is the piece of code of your operator:
template<typename T>
ostream& operator<<(ostream &os, Node<T> &n){
os << n->data;
return os;
}
The variable n it is passed by reference and you are accessing it with -> which expects a pointer. The reason why the code compiles is because when you call f << r you actually call the operator with a Node<T>* so the compiler does not use the template function which expects a Node<T>&. Which means the template function is never instantiated.
I think there is not much need for having the operator overload in this case. You can just simply call r->getData()
Also general things i noticed while looking at the code:
I would try to use unique_ptr
I would try to avoid using friend classes
I would refactor the code to not open and close the file at every recursive call
Let me know if you need any clarifications
I'm trying to write a friend function to go through a linked list and output the characters in the list, but for some reason I can't declare Nodes within the friend function. Here is my code:
This is the function:
std::ostream& operator<<(std::ostream& out, LinkedList& list)
{
Node *tempNode = nullptr;
*tempNode = *beginningOfList;
std::cout << "list: ";
while(tempNode)
{
std::cout << tempNode->letter;
if (tempNode->next)
std::cout << ", ";
tempNode = tempNode->next;
}
return out;
}
Here is the header file:
#ifndef _LINKED_LIST_
#define _LINKED_LIST_
#include <ostream>
class LinkedList
{
public:
LinkedList();
~LinkedList();
void add(char ch);
bool find(char ch);
bool del(char ch);
friend std::ostream& operator<<(std::ostream& out, LinkedList& list);
private:
struct Node
{
char letter;
Node *next;
};
Node *beginningOfList;
};
#endif // _LINKED_LIST_
When I try to compile it, I get the messages "Node was not declared in this scope," as well as "*tempNode was not declared in this scope" and "*beginningOfList was not declared in this scope." I'm guessing the problem has to do with namespaces, but I'm really not sure.
It's telling the truth. Node etc were not declared in that scope. Your operator is a global function but those things are in the scope of LinkedList. Try calling them LinkedList::Node, list->beginningOfList etc.