Hey guys I am trying to overload ifstream and ofstream but without any success.
Header File:
#include <iostream>
#include <fstream>
using namespace std;
class Complex
{
private:
double real;
double imaginary;
public:
//constructors
Complex();
Complex(double newreal, double newimaginary);
~Complex();
//setter
void setReal(double newreal);
void setImaginary(double newimaginary);
//getter
double getReal();
double getImaginary();
//print
void print();
//methods
Complex conjugate();
Complex add(Complex c2);
Complex subtraction(Complex c2);
Complex division(Complex c2);
Complex multiplication(Complex c2);
friend ifstream& operator >> (ifstream& in, Complex &c1)
{
in >> c1;
return in;
}
};
Test file:
#include <iostream>
#include <fstream>
#include <string>
#include "Complex2.h"
using namespace std;
int main()
{
Complex c1;
ifstream infile;
infile.open("in1.txt");
cout << "Reading from the file" << endl;
infile >> c1;
// write the data at the screen.
infile.close();
return 0;
}
I didnt think the cpp file was important since the header file includes the ifstream.
Everytime I run this program i get this error:
Reading from the file
Segmentation fault (core dumped)
I dont know how to fix it.
Thank you very much.
friend ifstream& operator >> (ifstream& in, Complex &c1)
{
in >> c1; // This is calling this function infinitely!!
return in;
}
The above code implements the operator>> for the Complex type. However, it is a recursive function with no stopping condition.
You probably should be do something similar to the following. Obviously, I don't know how the class was encoded so this is just for illustration.
friend ifstream& operator >> (ifstream& in, Complex &c1)
{
double real;
in >> real;
c1.setReal(real);
double imaginary;
in >> imaginary;
c1.setImaginary(imaginary);
return in;
}
I overlooked that it's a friend function so this could also work.
friend ifstream& operator >> (ifstream& in, Complex &c1)
{
in >> c1.real;
in >> c1.imaginary;
return in;
}
As mentioned in my comment, and in the other answer the operator>>() overload is just called recursively.
One of the most common approaches to fix that, is to declare a put() function in your Complex class like:
class Complex {
public:
// ...
private:
double real;
double imaginary;
istream& put(std::istream& is) {
is >> real;
is >> imaginary;
return is;
}
};
And let the global overload call that function:
friend ifstream& operator >> (ifstream& in, Complex &c1) {
return c1.put(in);
}
Related
I have a issue about my constructor is not correctly working. Whenever i run the program, my overloaded operator might not be perform correctly because i always get the default constructor values when i get the output with cout.
I believe that i made my constructor declarations well but all of my objects getting filled with 0 and Unknown
here is my txt file:
1 Prince Heins 25
2 Lady Bridgette 29
3 Tony Ann 223
4 Lucy Phoenix 35
Here is my code;
#include <iostream>
#include <string>
#include <conio.h>
#include <fstream>
#include <stdio.h>
#include <stdlib.h>
#include <sstream>
#include <istream>
#include <iomanip>
#include <cstring>
#include <ostream>
using namespace std;
class contact{
private:
int listno;
string name;
string surname;
string phonenumber;
public:
contact(){
this->name="Unknown";
this->surname="Unknown";
this->phonenumber="Unknown";
this->listno=0;
}
contact (string name,string surname,string phonenumber){
this->name=name;
this->surname=surname;
this->phonenumber=phonenumber;
}
contact(int listno,string name,string surname,string phonenumber){
this->name=name;
this->surname=surname;
this->listno=listno;
this->phonenumber=phonenumber;
}
friend ostream & operator<< (ostream &out, const contact &con){
out << con.listno << con.name << con.surname << con.phonenumber;
return out;
}
friend istream & operator>> (istream &in, contact &con){
in >> con.listno >> con.name >> con.surname >> con.phonenumber;
return in;
}
};
int main(){
ifstream pbin("phoneData2.txt");
string line;
long linecount;
for(linecount=0;getline(pbin,line);linecount++);
contact* myArray = new contact[linecount];
pbin.seekg(0);
if(pbin.is_open()){
int i;
for(i=0;i<linecount;i++){
if(pbin!=NULL){
while(pbin>>myArray[i]);
}
}
pbin.close();
cout << myArray[2]; // try attempt
return 0;
}
}
and here is my output for cout << Array[2];
OutputArray2
The problem results from the wrong used algorithm and wrongly placed statements.
So, let's look what is going on in the below:
long linecount;
for(linecount=0;getline(pbin,line);linecount++)
;
contact* myArray = new contact[linecount];
pbin.seekg(0);
if(pbin.is_open()){
int i;
for(i=0;i<linecount;i++){
if(pbin!=NULL) {
while(pbin>>myArray[i]);
}
}
pbin.close();
You want to count the lines. So you read all lines until the eofstate is set. But, additionally, also the fail bit will be set. See also here.
If you use your debugger, you will find a 3 in _Mystate.
Then you perform a seekg. This will reset the eof bit but keep the fail bit. The dubugger shows then
You can see that the fail bit is still set.
So, and this will now lead to the main problem. If your write if(pbin!=NULL) which is definitely wrong (on my machine is does not even compile), or if you better write if(pbin) the fail bit will still be set. And because the bool and the ! operator for streams is overwritten (please see here) the result of the if and while will be false and your pbin>>myArray[i] will never be executed.
So, a pbin.clear() would help.
But, although your class definition is already very good, with inserter and extractor overwritten, you do not use the full C++ power for reading the data.
One basic recommendation would be to never use raw pointers for owned memory. And best also not new. Use dedicated containers for your purpose. E.g. a std::vector. The you can use the std::vectors constructor no 5 together with a std::istream_iterator. Please read here. The range based constructor for the std::vector will copy data from a given range, denoted by the begin and end iterator. And if you use the std::istream_iterator, it will call your overwritten extractor operator, until all data are read.
So your main shrinks to:
int main() {
// Open source file and check, if it could be opened
if (ifstream pbin("r:\\phoneData2.txt");pbin) {
// Read complete source file
std::vector data(std::istream_iterator<contact>(pbin), {});
// Show data on console
std::copy(data.begin(), data.end(), std::ostream_iterator<contact>(std::cout, "\n"));
}
return 0;
}
This looks by far compacter and is easier to read. We start with an if-statement with initializer. The initializer parts defines the variable and the constructor will open the file for us. In the condition part, we simple write pbin. And, as explained above, its bool operator will be called, to check if everything was ok.
Please note:
We do not need a close statement, because the destructor of the
std::ifstream will close the file for us.
The outer namespace will not be polluted with the variable name pbin. That is one of the reasons, why ifstatement with initializer should be used.
We alread descibed the std::vector with its range constructor. SO reading the complete file is simple done by the very simple statement
std::vector data(std::istream_iterator<contact>(pbin), {});
Please note:
We do not define the type of the std::vector. This will be automatically deduced by the compiler through CTAD
We use the default initialzer {} for the end iterator, as can be seen here in constructor number 1.
The whole program could then be rewritten to:
#include <iostream>
#include <string>
#include <fstream>
#include <vector>
#include <algorithm>
#include <iterator>
using namespace std;
class contact {
private:
int listno;
string name;
string surname;
string phonenumber;
public:
contact() {
this->name = "Unknown";
this->surname = "Unknown";
this->phonenumber = "Unknown";
this->listno = 0;
}
contact(string name, string surname, string phonenumber) {
this->name = name;
this->surname = surname;
this->phonenumber = phonenumber;
}
contact(int listno, string name, string surname, string phonenumber) {
this->name = name;
this->surname = surname;
this->listno = listno;
this->phonenumber = phonenumber;
}
friend ostream& operator<< (ostream& out, const contact& con) {
out << con.listno << '\t' << con.name << '\t' << con.surname << '\t' << con.phonenumber;
return out;
}
friend istream& operator>> (istream& in, contact& con) {
in >> con.listno >> con.name >> con.surname >> con.phonenumber;
return in;
}
};
int main() {
// Open source file and check, if it could be opened
if (ifstream pbin("r:\\phoneData2.txt");pbin) {
// Read complete source file
std::vector data(std::istream_iterator<contact>(pbin), {});
// Show data on console
std::copy(data.begin(), data.end(), std::ostream_iterator<contact>(std::cout, "\n"));
}
return 0;
}
I need to create an ADT for an assignment. I have my class definition in a header file as follows:
#ifndef PHONECALL_H
#define PHONECALL_H
#include <iostream>
using namespace std;
class PhoneCall
{
public:
PhoneCall();
PhoneCall(string newNumber);
~PhoneCall();
string getNumber()const;
int getLength()const;
float getRate()const;
float calcCharge(); //calcuates total cost of call
friend bool operator==(const PhoneCall & call1, const PhoneCall & call2);
friend istream& operator >>(istream& in, PhoneCall& call);
friend ostream& operator <<(ostream& out, const PhoneCall& call);
private:
string number;
int length;
float rate;
};
All the bodies of the functions are in the implementation file (no errors there)
Then in the main application file, when I call the calcCharge() function, I get:
error: 'calcCharge()' was not declared in this scope
This is the only error I get. Here is the application file code:
#include <iostream>
#include <fstream>
#include "PhoneCall.h"
using namespace std;
int main()
{
string num, cellNum;
int length;
float rate, total;
cout << "Enter a phone number: " << endl;
cin>> num;
PhoneCall theCall(num);
ifstream read;
while (read >> cellNum >> length >> rate)
{
if (cellNum == num)
{
total += calcCharge();
}
}
return 0;
}
I know the code for the main application is incomplete, but due to this error I am not able to test whether the program is doing what I need it to do.
It's a member of the class.
total += theCall.calcCharge();
This is my header file. Im trying to overload the istream operator and use ifstream in my main function to read in a text file with structured data (rows and columns). I am getting the error "[Error] no match for 'operator>>' (operand types are 'std::istringstream {aka std::basic_istringstream}' and 'std::string {aka std::basic_string}')
I commented where I am getting the error.
My main function is basically empty so far besides The class and object.
#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
using namespace std;
class Record
{
private:
string name;
int id;
double rate;
double hours;
public:
Record();
Record (string n, int empid, double hourlyRate, double hoursWorked);
// constructor
void read_data_from_file();
double calculate_wage();
void print_data();
/* SETTERS AND GETTERS */
void set_name (string n);
string get_name();
void set_id (int empid);
int get_id();
void set_rate (double hourlyRate);
double get_rate();
void set_hoursWorked(double hoursWorked);
double get_hoursWorked();
/* END OF SETTERS AND GETTERS */
friend istream& operator >> (istream& is, Record& employee)
{
string line;
getline (is, line);
istringstream iss(line);
iss >> employee.get_name(); // where i get error
}
};
You have to change the get_name() to return a non-const reference, like string& get_name(); to get it working/compile. But will look strange.
What you can do instead is pass the member name directly
iss >> employee.name;
that's what friends do.
And don't forget to return the stream is.
I have only one custom class with .h and .cpp files but I get error while trying to create an instance of this class from main.cpp (using IDE clion).
I am just a beginner and reading C++ primer learning class, if there are some inappropriate things please point out.
main.cpp
#include "Fun.h"
void Solve();
int main()
{
Solve();
return 0;
}
void Solve()
{
Sales_data total;
if(read(cin,total)){ //read the first record
Sales_data temp;
while(read(cin,temp)){
if(temp.isbn() == total.isbn())
total.combine(temp);
else{
print(cout,total) << endl;
total = temp;
}
}
print(cout,total);
}//if
else{
cerr << "No data!?" << endl;
}
}
Fun.cpp
#include "Fun.h"
using std::istream;
using std::ostream;
double Sales_data ::avg_price() const {
if(units_sold)
return revenue/units_sold;
else
return 0;
}
Sales_data& Sales_data:: combine(const Sales_data& rhs){
units_sold += rhs.units_sold;
revenue += rhs.revenue;
return *this;
}
istream &read(istream &is,Sales_data &item)
{
double price = 0;
is >> item.bookNo >> item.units_sold >> price;
item.revenue = price * item.units_sold;
return is;
}
ostream &print(ostream &os, const Sales_data &item)
{
os << item.isbn() << " " << item.units_sold << " "
<< item.revenue << " " << item.avg_price() ;
return os;
}
Sales_data add(const Sales_data& lhs,const Sales_data& rhs)
{
Sales_data sum = lhs;
sum.combine(rhs);
return sum;
}
Fun.h
#ifndef PROJECT1_FUN_H
#define PROJECT1_FUN_H
#include <cstdio>
#include <cstring>
#include <cassert>
#include <vector>
#include <iostream>
using std::istream;
using std::ostream;
using std :: cin;
using std :: cout;
using std :: cerr;
using std :: endl;
struct Sales_data{
std::string isbn()const{return bookNo;}
Sales_data& combine(const Sales_data&);
double avg_price() const;
std::string bookNo;
unsigned units_sold = 0;
double revenue = 0;
};
Sales_data add(const Sales_data&,const Sales_data&);
istream &read(istream &,Sales_data &);
ostream &print(ostream &,Sales_data &);
#endif //PROJECT1_FUN_H
This is the error information:
I wonder what caused the problem?
I think the problem is that declaration and definition of the print function are different (the Sales_data parameter is a reference in declaration while is a constant reference in definition):
ostream &print(ostream &,Sales_data &); // Fun.h
ostream &print(ostream &os, const Sales_data &item) // Fun.cpp
Change the declaration in the header file to:
ostream &print(ostream &, const Sales_data &);
I have to make a program to display the weather in Sheffield since 1930.
I have to use sheffield.data for the record.
I have 3 files. Data.cpp, Data.hpp and analyze.cpp
analyze.cpp:
#include <istream>
#include <fstream>
#include <vector>
#include "data.hpp"
using namespace std;
int main()
{
MonthData data();
vector<MonthData> vectorData;
ifstream file ("sheffield.data");
string line;
int l_num = 0;
if (file.is_open()) {
while (getline(file, line))
if (l_num < 4) {
l_num += 1;
}
else {
file >> data;
vectorData.push_back(data);
}
float MinimumDeg = vectorData[0].getMinimum();
int year = vectorData[0].getYear();
for ( size_t a = 0; a < vectorData.size(); a++)
{
MinimumDeg = vectorData[a].getMinimum();
year = vectorData[a].getYear();
}
cout << "Lowest year and month lowest rainfall: '\n'" << "Min Temp;" << MinimumDeg << "C '\n'" << "Year" << year << endl;
return 0;
}
}
:
data.cpp
#include "data.hpp"
#include <iostream>
using namespace std;
istream& operator >> (istream& in, MonthData& data)
{
in >> data.year >> data.year >> data.temp_maximum >> data.temp_minimum >> data.air_frost >> data.rain >> data.sun;
return in;
}
data.hpp:
#ifndef DATA_HPP
#define DATA_HPP
#include <iostream>
#include <string>
#include <cmath>
using namespace std;
class MonthData
{
friend istream& operator >> (istream&, MonthData&);
public:
//overload constructor
MonthData(double, int, double, double, int, double, double);
//Accessor functions
double getYear() const { return year; } //returns the year
int getMonth() const { return month; } //returns the month
double getMaximum() const { return temp_maximum; } //returns maximum temperature
double getMinimum() const { return temp_minimum; } //returns minimum temperature
int getFrost() const { return air_frost; } //returns air frost
double getRain() const { return rain; } //returns rainfall
double getSun() const { return sun; } //returns no of hours of sunshine
private:
double year;
double month;
double temp_maximum;
double temp_minimum;
int air_frost;
double rain;
double sun;
};
#endif
Why am I getting this error?
[sc14da#cslin035 cw]$ g++ data.cpp data.hpp analyze.cpp -o analyze
analyze.cpp: In function ‘int main()’:
analyze.cpp:11: error: no matching function for call to ‘MonthData::MonthData()’
data.hpp:17: note: candidates are: MonthData::MonthData(double, int, double, double, int, double, double)
data.hpp:12: note: MonthData::MonthData(const MonthData&)
If you do not provide any constructor in your class, the compiler will automatically create one for you.
In your class, you have specified a particular constructor:
MonthData(double, int, double, double, int, double, double);
As soon as you provide any constructor, the compiler will not create a default constructor (i.e. one that takes no parameters).
You are calling
MonthData data();
You are passing no parameters here but you have no constructor that takes no parameters.
You probably meant to call
MonthData data(with 7 parameters);
Alternatively, add the following to your MonthData class body:
MonthData();
Then in your data.cpp, need to provide the code for what this constructor should do, i.e.
MonthData::MonthData()
{
//Initialise as required - but better to use a member initialization list
}
It would be better to use a member initialization list for your 7 member variables.
For example:
MonthData::MonthData()
: year(2014), month(2), temp_maximum(15.4), temp_minimum(2.1), air_frost(5), rain(5.6), sun(7.6) //Use desired default values
{}
This simple constructor code could instead be put directly in the class body in the header file:
class MonthData
{
public:
//overload constructor
MonthData(double y, int m, double max, double min, int fr, double r, double s)
: year(y), month(m), temp_maximum(max), temp_minimum(min), air_frost(fr), rain(r), sun(s) {};
//default constructor
MonthData()
: year(2014), month(2), temp_maximum(15.4), temp_minimum(2.1), air_frost(5), rain(5.6), sun(7.6) {};
etc
};
In addition - review your variable types. Should year really be a double? Also you have month declared as a double but your accessor returns an int.
That's not surprising as you haven't included a default constructor. Or, more specifically, a constructor that matches this line:
MonthData data();
Solution: add a default constructor in your base MonthData class (data.hpp).