I am trying to read and display the contents of a file named myDocument.txt, but I always get the following error with my header file.
./ReadDocument.h:22:24: error: expected parameter declarator std::ifstream myflux("myDocument.txt");
What's going on?
Here is my ReadDocument.h:
class ReadDocument{
public:
ReadDocument(); //empty constructor
ReadDocument(const std::string& fileName); //constructor
void documentContent();
friend std::ostream& operator <<(std::ostream& os, const ReadDocument& d);
std::list<std::string> myList;
std::ifstream myflux("myDocument.txt");
if(myflux){
//Getting the words from the file string by string
std::string data;
while(myflux>>data){
myList.push_back(data);
}
myflux.close();
}
else{
std::string message = "\t\tERROR ==> This file doesn't exist.";
throw FileDoesntExistException(message);
}
};
Here is my ReadDocument.cpp:
#include "ReadDocument.h"
ReadDocument::ReadDocument(){}
void ReadDocument::documentContent(){}
std::ostream& operator <<(std::ostream& os, const ReadDocument& d){
for(std::list <std::string> :: const_iterator it = ReadDocument::myList.begin(); it!=ReadDocument::myList.end(); it++)
std::cout<<*it<<std::endl;
return os;
}
And this is my UseReadDocument.cpp
#include "ReadDocument.h"
int main(){
ReadDocument rd("test.txt");
std::cout<<rd<<std::endl;
return 0;
}
I tried renamed the file and still the same problem.
I put it in the class, and doesn't change anything.
I always have the same error coming out.
and yes it is my entire code
The part of your class after myflux is not in a method.
Did you want to put the code in the function documentContent, like this?
ReadDocument.h:
class ReadDocument{
public:
ReadDocument(); //empty constructor
ReadDocument(const std::string& fileName); //constructor
void documentContent();
friend std::ostream& operator <<(std::ostream& os, const ReadDocument& d);
std::list<std::string> myList;
std::ifstream myflux("myDocument.txt");
};
ReadDocument.cpp:
#include "ReadDocument.h"
ReadDocument::ReadDocument(){}
void ReadDocument::documentContent(){
if(myflux){
//Getting the words from the file string by string
std::string data;
while(myflux>>data){
myList.push_back(data);
}
myflux.close();
}
else{
std::string message = "\t\tERROR ==> This file doesn't exist.";
throw FileDoesntExistException(message);
}
}
std::ostream& operator <<(std::ostream& os, const ReadDocument& d){
for(std::list <std::string> :: const_iterator it = ReadDocument::myList.begin(); it!=ReadDocument::myList.end(); it++)
std::cout<<*it<<std::endl;
return os;
}
By the way, you should avoid creating an empty constructor and filling it with nothing.
Since C++11 you should write ReadDocument() = default; in your header and remove ReadDocument::ReadDocument(){} from the cpp.
With your class your are declaring two public variables and trying to give each instance of your class these default characteristics. The solution in to put the default conditions in the default constructor as follows:
class ReadDocument{
private:
std::list<std::string> myList; //moved member variables to private
std::ifstream myflux; //part of class
public:
ReadDocument(); //empty constructor
ReadDocument(const std::string& fileName); //constructor
void documentContent();
friend std::ostream& operator <<(std::ostream& os, const ReadDocument& d);
};
Implementation:
#include "ReadDocument.h"
ReadDocument::ReadDocument()
{
myflux.open("myDocument.txt");
if(myflux){
//Getting the words from the file string by string
std::string data;
while(myflux>>data){
myList.push_back(data);
}
myflux.close();
}
else{
std::string message = "\t\tERROR ==> This file doesn't exist.";
throw FileDoesntExistException(message);
}
}
void ReadDocument::documentContent(){}
std::ostream& operator <<(std::ostream& os, const ReadDocument& d){
for(std::list <std::string> :: const_iterator it =
d.myList.begin(); it!=d.myList.end(); it++)
std::cout<<*it<<std::endl;
return os;
}
Code will now associate myflux with "myDocument.txt" and extract the file data into myList by default (unless instantiated with string parameter for use with const string& constructor) for each instance of the ReadDocument class. As well as a few other fixes in the ostream function.
P.S* Assuming this is your entire .cpp file associated with the ReadDocument class, you forgot to implement the constructor containing the const string& parameter, ReadDocument(const std::string& fileName).
Related
I'm currently working on a program with C++ 14; basically I was implementing a template class called Database and i wanted to differentiate the constructor of this template class basing it on different specialization of my template. In other words i wanted it to do different things when I specialize my type with a specific class. in my example I wanted to do different things when i pass the class boat to it (boat is define by a constructor with 5 strings).
'''
#include"boat.h"
#include<vector>
#include<iostream>
#include<string>
#include<fstream>
using namespace std;
template <typename T>
class Database{
public:
Database(const string& file_name);
~Database();
void Add (const string& file_list);
void Upload (const string& file_list);
vector <T> get_vector();
protected:
vector <T> _list;
vector <T>_new_element;
string token,st;
string delimiter=";";
size_t pos=0;
vector <string> temp;
fstream f;
int max_id;
};
template <>
class Database<boat>
{
friend class boat;
public:
Database(const string& file_name){
f.open(file_name);
//controllo apertura file
if (f.is_open()) {
while ((getline(f, token))) {
while ((pos = token.find(delimiter)) != (string::npos)) {
st = token.substr(0, pos);
tempg.push_back(st);
token.erase(0, pos + delimiter.length());
}
tempg.push_back(token);
_list.push_back(boat(tempg[0],tempg[1],tempg[2],tempg[3],tempg[4]));
pos = 0;
tempg.clear();
}
}
};
~Database();
void Add (const string& file_list);
void Upload (const string& file_list);
const vector <boat> get_vector();
protected:
vector <boat> _list;
boat _new_element();
string token,st;
string delimiter=";";
size_t pos=0;
vector <string> tempg;
ifstream f;
};'''
So basically I did this method with the constructor to open a file and read the important data of the class boat which were divided by ';'.
My question is: how i have to define the syntax for the template constructor specialization, when I pass to the template not a normal type like int, char or other, but when I pass a class. Because it give me the error:
boat was not declared in this scope class Database.
How do I declare it right?
You can do somethimng like this:
template<>
Database<boat>::Database(const string& file_name)
{
// ... your stuff here ...
}
But I think that the more correct design is to have template implementation of the constructor and then have stream input and output operartors for the class boat, i.e.
std::istream& operator>>(std::istream& is, boat& obj)
{
// ... actual input here ...
return is;
}
std::ostream& operator<<(std::ostream& os, const boat& obj)
{
// ... actual output here ...
return os;
}
and then use them to load/store data in the file.
I have a class CPerson
class CPerson
{
private:
string name;
string egn;
public:
CPerson() {};
CPerson(string getname, string getegn)
{
name = getname;
egn = getegn;
}
bool operator < (const CPerson &obj)
{
...
}
bool operator ==(const CPerson &obj)
{
...
}
friend ostream& operator << (ostream& out, const CPerson &obj) //извеждане в поток - конзола
{
...
}
friend istream& operator >> (istream& in, CPerson &obj) //четене от поток - конзола
{
...
}
friend ofstream& operator <<(ofstream& out, const CPerson& obj) // извеждане в поток - файл
{
...
}
friend ifstream& operator >>(ifstream& in, CPerson& obj) // четене от поток - файл
{
...
}
I made another class CCity which has a vector of objects CPerson
class CCity
{
private:
string city_name;
vector <CPerson> people;
public:
CCity() {};
CCity(string filename)
{
string name, egn;
ifstream file(filename);
file >> city_name;
while (file >> egn >> name)
{
people.push_back(CPerson(name, egn));
}
}
friend ostream& operator <<(ostream& out, const CCity& obj)
{
vector<CPerson>::iterator iter;
for (iter = people.begin(); iter != people.end(); iter++)
{
}
}
};
I am trying to overload the output operator so I can output my vector of objects but I get the error "left of '.begin' must have class/struct/union". I can't see anything wrong with my code. I have include and
At very first:
friend ostream& operator <<(ostream& out, const CCity& obj);
does not define a member function! Declaring the function (operator) as friend makes it a free-standing one, even if defined inside the class. So there's no people object inside. You need to refer to by obj.people!
Then why do you declare iter in front of the loop? Do you need the iterator for any reason afterwards? If not, prefer keeping it local to for loop. Then you can additionally let the type get deduced: for(auto iter = .... auto will additionally cover another error: obj is const, so obj.people is const as well. And the begin overload for constant objects won't return an iterator, but a const_iterator! Be aware that there are two versions of begin:
iterator begin();
const_iterator begin() const; // <- that one will be called on const objects!
Would you break the loop in between? If not, you could use a range based for loop as well: for(auto& person : obj.people). Again the type of person gets deduced, as we explicitly told auto to be a reference, type will be Person const&.
Whichever variant you chose, you now can output the person:
out << *iter;
out << person;
Assuming they were public, you could access the person's attributes as well:
iter->name;
person.name;
I'm trying to overload operator<< in C++ to use a recursive private method to get the content of a binary search tree as a string. I keep getting the "not declared in this scope" error despite checking the method signature for inconsistencies. I don't understand why the call to recursiveOutput() in operator<< causes this error.
operator<< definition:
friend std::ostream& operator<<(std::ostream&, const BinTree&);
recursive method definition:
void recursiveOutput(Node*, string&);
operator<< implementation:
std::ostream& operator<<(std::ostream& os, const BinTree& rhs)
{
string result;
recursiveOutput(rhs.root, result);
os << result;
return os;
}
The BinTree class has the private member "root" which is a pointer to the structure "Node".
EDIT: Example code
class BinTree
{
public:
friend std::ostream& operator<<(std::ostream&, const BinTree&);
private:
struct Node
{
string data;
Node* left;
Node* right;
};
Node* root;
void recursiveOutput(Node*, string&);
};
std::ostream& operator<<(std::ostream& os, const BinTree& rhs)
{
string result;
rhs.recursiveOutput(rhs.root, result);
os << result;
return os;
}
void BinTree::recursiveOutput(Node* currentRoot, string& result)
{
// if currentRoot is NULL return
if (currentRoot == NULL)
{
return;
}
// traverse left branch
recursiveOutput(currentRoot->left, result);
// append string from NodeData
std::ostringstream stream;
stream << *currentRoot->data;
result.append(stream.str());
result.append(" ");
// traverse right branch
recursiveOutput(currentRoot->right, result);
}
EDIT: The reason this causes an error is because operator<< is not a member of BinTree, so it cannot call a member function without a BinTree object to call it.
I am new to C++ programming and am having trouble implementing this operator overloading. It gives the error that no operator "<<" matches these operands.
class class1{
public:
bool operator==(class1 &);
friend ostream & operator<<(ostream &, class1 &);
private:
string name;
};
/*Friend ostream & operator <<*/
ostream & operator << (ostream & os, class1 & obj){
os << obj.name;
return os;
}
Someone mentioned I need another overloaded operator, but I can't figure out how to make it work with another overloaded operator
Here is the situation with your code; you have a private member string variable within your class where no outside object can set this variable. Your class does not contain a defined constructor nor a setting method. When I tried your code I had to change your operator declaration and definition from this:
std::ostream& operator<<( std::ostream& os, class1& obj );
to this:
std::ostream& operator<<( std::ostream& os, const class1& obj );
in order for it to compile. However when it came to building the project I was getting a Linker Error of an unresolved identifier. What was happening here is that the ostream object that you are declaring as a friend to your class object does know about the private member string but it can not do anything with it since this string is empty or not valid. I changed your class to this:
#include <conio.h>
#include <string>
#include <iostream>
class class1 {
friend std::ostream& operator<<( std::ostream& out, const class1& other );
private:
std::string m_strName;
public:
explicit class1( std::string& strName ) : m_strName( strName ) {}
void setName( std::string& strName ) { m_strName = strName; }
std::string getName() const { return m_strName; }
};
std::ostream& operator << ( std::ostream& out, class1& obj ) {
out << obj.m_strName << std::endl;
// out << obj.getName() << std::endl;
return out;
}
int main() {
class1 a( std::string( "class1" ) );
std::cout << a << std::endl;
std::cout << "Press any key to quit" << std::endl;
_getch();
return 0;
}
This compiles, builds, links and executes properly and displays appropriate text and exits with a value of 0 for no errors. I am using MSV2013 on a Win7 machine. The main issue was that since your class had no way to populate its string member upon construction the ostream operator object could not resolve the variable in use.
The overload operator<<(std::ostream&, std::string) is actually defined by #include <string>.
Although std::string is also defined by that header, it is still possible for std::string to be defined but not this operator overload, if you did not include that header.
The C++ standard requires that certain headers provide certain features, but it does not prohibit that feature also being provided by another header. In your case, the compiler/library writer has decided that implementing some other feature in another header was most easily done by defining std::string, but it would have done this by having a separate file defining std::string which is included both by <string> and by the other header.
remove the keyword "friend" for ostream if you intent for it to be a public member. If your want ostream to be friend move it above public:
operator== should have two const parameter, const if you do not intend to change.
friend ostream & operator<<(ostream &, const class1 &);
public:
bool operator==(const class1& x, const class1& y);
or
public:
bool operator==(const class1& x, const class1& y);
ostream & operator<<(ostream &, const class1 &);
make operator << second parameter a const might help
ostream & operator << (ostream & os, const class1 & obj){
os << obj.name;
return os;
}
Was just playing with operator overloading and couldn't find out whats wrong with the below code -
#include <iostream>
class Holder
{
public:
std::string name;
int data;
};
std::istream operator>>(std::istream& is, Holder &h)
{
std::cout<<"Enter name = "<<std::endl;
std::cin>>h.name;
std::cout<<"Enter data = "<<std::endl;
std::cin>>h.data;
return is;
}
std::ostream operator<<(std::ostream& os, Holder const &h)
{
std::cout<<"Name = "<<h.name<<std::endl;
std::cout<<"Data = "<<h.data<<std::endl;
return os;
}
int main(int argc, char **argv) {
Holder h;
std::cin>>h;
std::cout<<h;
}
The error my MinGW compiler gives is -
In file included from c:\mingw\bin\../lib/gcc/mingw32/4.6.1/include/c++/ios:45:0,
from c:\mingw\bin\../lib/gcc/mingw32/4.6.1/include/c++/ostream:40,
from c:\mingw\bin\../lib/gcc/mingw32/4.6.1/include/c++/iostream:40,
from ..\src\Main.cpp:1:
c:\mingw\bin\../lib/gcc/mingw32/4.6.1/include/c++/bits/ios_base.h: In copy constructor 'std::basic_ios<char>::basic_ios(const std::basic_ios<char>&)':
c:\mingw\bin\../lib/gcc/mingw32/4.6.1/include/c++/bits/ios_base.h:788:5: error: 'std::ios_base::ios_base(const std::ios_base&)' is private
c:\mingw\bin\../lib/gcc/mingw32/4.6.1/include/c++/bits/basic_ios.h:64:11: error: within this context
In file included from c:\mingw\bin\../lib/gcc/mingw32/4.6.1/include/c++/iostream:41:0,
from ..\src\Main.cpp:1:
c:\mingw\bin\../lib/gcc/mingw32/4.6.1/include/c++/istream: In copy constructor 'std::basic_istream<char>::basic_istream(const std::basic_istream<char>&)':
c:\mingw\bin\../lib/gcc/mingw32/4.6.1/include/c++/istream:57:11: note: synthesized method 'std::basic_ios<char>::basic_ios(const std::basic_ios<char>&)' first required here
..\src\Main.cpp: In function 'std::istream operator>>(std::istream&, Holder&)':
..\src\Main.cpp:18:9: note: synthesized method 'std::basic_istream<char>::basic_istream(const std::basic_istream<char>&)' first required here
Return by reference:
std::istream& operator>>(std::istream& is, Holder &h)
std::ostream& operator<<(std::ostream& os, Holder const &h)
//^
as streams are not copyable.