Operator overloading using constructor add two Complex number - c++

I wanted to get a value from the user via using constructor and another value will be in the program itself. I try to code it as below. But constructor is initializing all the values to 0,0(no argument). What to do?
#include<iostream>
using namespace std;
class complex
{
float x;
float y;
public :
complex() //no argument constructor
{
/* cout<<"Enter real = ";
cin>>x;
cout<<"Enter imaginary = ";
cin>>y;*/
}
complex(float real, float imag)
{
cout<<"Enter real = ";
cin>>x;
cout<<"Enter imaginary = ";
cin>>y;
x = real;
y = imag;
}
complex operator+(complex);
void display(void);
};
complex complex :: operator+(complex c)
{
complex temp;
temp.x = x + c.x;
temp.y = y+c.y;
return(temp);
}
void complex :: display(void)
{
cout<<x<<" +i"<<y<<"\n";
}
int main()
{
complex c1,c2(2.5,1.7),c3(0,0);
c3 = c1+c2;
c1.display();
c2.display();
c3.display();
system ("PAUSE");
// return 0;
}

Below is probably what you would want.
I changed your Complex number class to only use one constructor that has default parameters both will default to 0 if you do not provide any parameters.
In your code your parameter less function does nothing and defaults to just using the default constructor for x and y (in the case of floats using 0). You can combine this with the parametered constructor by using default parameters, as mentioned above.
This makes it explicit that if you don't provide values to the Complex constructor you should expect x and y to be 0.
I also added input and output stream operators, but that may not be necessary for your uses.
But it allows you to use cin >> c1; and it is apparent that you expect the user to input the values for c1, instead of embedding that code in the default constructor.
#include<iostream>
using namespace std;
class complex{
float x;
float y;
public :
// it seems like one constructor with default parameters
// should work for your case.
complex(float real = 0, float imag = 0):x(real),y(imag){}
complex operator+(complex);
friend ostream& operator << (ostream& outs, Complex C);
friend istream& operator << (istream& ins, Complex C);
};
ostream& operator << (ostream& outs, Complex C){
cout << C.x << " + i" << C.y;
return outs;
}
istream& operator << (istream& ins, Complex C){
if (ins == cin){
cout << "Enter real part" << endl;
ins >> C.x;
cout << "Enter imaginary part" << endl;
ins >> C.y;
} else {
ins >> C.x >> C.y;
}
return ins;
}
// your plus operator is fine.
int main(){
complex c1,c2(2.5,1.7),c3(0,0); //c1 will have x = 0, y = 0
c3 = c1+c2; // c3.x = 2.5, c3.y = 1.7
cout << c1 << endl; // displays 0 + i0
cout << c2 << endl; // displays 2.5 + i1.7
cout << c3 << endl; // displays 2.5 + i1.7
return 0;
}
Output:
0 + i0
2.5 + i1.7
2.5 + i1.7
If this is not what you expect for output, what would you expect?

I have made a couple of assumptions and modified your code accordingly, the assumptions are:
The second constructor constructs values from the ones present in the main function, so we need a different constructor to create object using the input
c1 contains the values entered by the user and c3 is created using default constructor
Keeping the above in mind the code can be modified as follows:
#include<iostream>
using namespace std;
class complex
{
float x;
float y;
public :
complex() {}
complex(float real, float imag) { x=real; y=imag; } //constructor for creating x and y from values given in the code
complex(istream&);//constructor for creating values entered as input
complex operator+(complex);
void display(void);
};
//definition for constructor for taking user input
complex::complex(istream& in)
{
cout<<"Enter real = ";
in>>x;
cout<<"Enter imaginary = ";
in>>y;
}
complex complex :: operator+(const complex& c) const
{
complex temp;
temp.x = x + c.x;
temp.y = y+c.y;
return(temp);
}
void complex :: display(void)
{
cout<<x<<" +i"<<y<<"\n";
}
int main()
{
complex c1(cin),c2(2.5,1.7),c3;
//note the changes, c1 is made from user input, c2 from constructor and c3 using default constructor
c3 = c1+c2;
c1.display();
c2.display();
c3.display();
}
Make note of the modifications made which I have indicated by the comment lines

Related

How to use Complex numbers in Class/Object C++

Im strugling to implement complex numbers into my code. When I compile it gives me random numbers. It should use imaginary number i = sqrt(-1). It should output realPart + imaginaryPart * i.
#include <iostream>
#include <complex>
using namespace std;
class Complex
{
private:
double i;
complex<double> imaginarypart = i*sqrt(1);
double realpart;
public:
void seti(double a1) {
i = a1;
}
void setrealpart(double a2) {
realpart = a2;
}
void printwhole() {
cout << realpart + imaginarypart;
}
};
int main()
{
double a, b;
cout << "Enter your realpart" << endl;
cin >> a;
cout << "Enter your imaginarypart " << endl;
cin >> b;
Complex num1;
num1.seti(b);
num1.setrealpart(a);
cout << endl;
num1.printwhole();
}
The point is that an the type double cannot store imaginary values.
Yet you try to do so, e.g. with sqrt(1); (though you probably meant -1).
The complex<double> is indeed able to store imaginary values, but on the one hand it won't work by assigning the product of the non-initialised i with 1 and on the other hand you seem to try to implement complex numbers yourself. Using the provided complex standard type somewhat defeats that. If you use it, then you just need to learn outputting it in the format you want, instead of doing all the implementation work.
Lets assume that you are more interested in getting it done yourself first.
What you need to do is to always represent complex numbers as two numbers.
I hence propose to change your code likes this.
#include <iostream>
using namespace std;
class Complex
{
private:
/* double i; Won't work, it cannot store imaginary values. */
double imaginarypart;
double realpart;
public:
void setimaginarypart(double a1) {
imaginarypart = a1;
}
void setrealpart(double a2) {
realpart = a2;
}
void printwhole() {
cout << realpart << '+' << imaginarypart << 'i'; // To get the output you want.
}
};
int main()
{
double a, b;
cout << "Enter your realpart" << endl;
cin >> a;
cout << "Enter your imaginarypart " << endl;
cin >> b;
Complex num1;
num1.setimaginarypart(b);
num1.setrealpart(a);
cout << endl;
num1.printwhole();
}
Alternatively use existing solutions (e.g. std::complex), instead of trying to program one yourself. Outputting them in the shape you want (r+i*I) does not require to implement the whole thing yourself.
Have a look at https://en.cppreference.com/w/cpp/numeric/complex to learn about what it offers.
As you figured out, complex numbers have a real and an imaginary part. And in std::complex<double>, those two parts are combined.
But in your class Complex, you have Complex::i, Complex::realpart, Complex::imaginarypart::real() and Complex::imaginarypart::imag(). That's 4 parts!
Furthermore, complex<double> imaginarypart = i*sqrt(1); means that Complex::imaginarypart is set to i*sqrt(1) when a Complex object is created. But at that time, i is still uninitialized! So that won't work either. This is why you get random numbers (or a crash, depending on your luck).
The simple solution is to drop your whole class Complex. std::complex<double> already has functions to set the real and imaginary parts, namely std::complex<double>::real(double) and std::complex<double>::imag(double)
(Note: real and imag are setters if you pass a value, getters if you don't).

c++ runtime error with code (classes/constructors)

I seem to be getting two errors:
A) The first iteration of the loop prints out values fine, however if I press 'y' to go for round 2 it autofills the first number as '0/0'. Shown in the image
B) I want to use the third constructor to set numerator = num and denominator = den However, it just seems to set to default values so I made a temporary fix by commenting out the constructor "Rational(num, den)" and physically wrote out numerator = num; and denominator = den;
Any help is appreciated!
// Add appropriate headers
#include <iostream>
#include <cstdlib>
#include <string>
#include <cmath>
#include <sys/time.h>
using namespace std;
/* KEEP THIS COMMENT
* class Rational
* represents a Rational number. Remember rational means ratio-nal
* which means there is a numerator and denominator having
* integer values. Using good ADT techniques, we have made member
* variable private (also known as instance variables) and made member
* functions public.
*/
class Rational
{
private:
int numerator;
int denominator;
public:
// ToDo: Default Constructor
Rational();
// ToDo: Constructor that takes int numerator
Rational(int i);
// ToDo: Constructor that takes int numerator and int denominator
Rational(int p, int q);
// ToDo: Member function to read a rational in the form: n/d
void input();
// ToDo: Member function to write a rational as n/d
void output();
// ToDo: declare an accessor function to get the numerator
int getNumerator();
// ToDo: declare an accessor function to get the denominator
int getDenominator();
// ToDo: delcare a function called Sum that takes two rational objects
// sets the current object to the sum of the given objects using the
// formula: a/b + c/d = ( a*d + b*c)/(b*d)
void sum(Rational a, Rational b);
// test if two rational numbers are equal.
bool isEqual(const Rational& op);
};
int main()
{
// ToDo: declare three rational objects using the default constructor
Rational a, b, c;
char answer='Y';
// Main loop to read in rationals and compute the sum
do {
cout << "\nEnter op1 (in the format of p/q): ";
a.input();
//Debug line
a.output();
// ToDo: use your input member function to read the first rational
cout << "\nEnter op2 (in the format of p/q): ";
// ToDo: use your input member function to read the second rational
b.input();
//Debug line
b.output();
// ToDo: use the third rational to call Sum with first and second as parameters
c.sum(a, b);
cout << "\nThe sum of op1 and op2 is: ";
c.output();
// ToDo: ouptput the third rational
cout << endl;
cout << "\nTry again (Y/N)?";
cin >> answer;
} while (answer == 'y' || answer == 'Y');
// ToDo: test getters
cout << "\nC's numerator is: " << c.getNumerator() << endl;
cout << "\nC's denominator is: " << c.getDenominator() << endl;
// TODO: Use two constructors to declare a whole number 3/1 and a 4/5
// TODO: Use output to print both rationals
//cout << .output() << " " << .output() << endl;
return 0;
}
// ToDO: Implement your class member functions below.
Rational::Rational()
{
numerator = 0;
denominator = 1;
}
Rational::Rational(int i)
{
numerator = i;
denominator = 1;
}
Rational::Rational(int p, int q)
{
numerator = p;
denominator = q;
}
void Rational::sum(Rational a, Rational b)
{
int num = (a.numerator*b.denominator + a.denominator*b.numerator);
int den = (a.denominator*b.denominator);
numerator = num;
denominator = den;
}
void Rational::input()
{
string in;
int num,den;
//cout << "Enter a rational number in the form of x/y : ";
getline(cin, in);
// find the index position of /
int indx = in.find("/");
// seperator out the numerator
num = atoi(in.substr(0, indx).c_str());
// seperate out the denominator
den = atoi(in.substr(indx+1, in.length()).c_str());
// Rational(num, den);
//cout <<num << " " <<den << endl; // Debug Line
numerator = num;
denominator = den;
//cout <<numerator << " " <<denominator << endl; // Debug Line
}
void Rational::output()
{
cout << numerator << "/" << denominator;
}
// Two getter functions
int Rational::getNumerator()
{
return numerator;
}
Here is the solution. Let me know if you don't know what Buffer is or why do we flush it. I'll try to explain further.
cout << "\nTry again (Y/N)?"; //In main
cin >> answer;
cin.ignore(256,'\n'); // Flush the buffer
Here is the explanation.
Yeah, it(cin) will work fine, As cin doesn't have any issue with buffer. But the issue is with getline. Now let's explain why. First, you need to know how the computer takes input in the program. Whenever you cin some value like cin>>x. The value doesn't directly go into x. Firstly it is stored in some temporary location named buffer. That's why you can press backspace on your console. If it directly writes in more variable(memory), you can't press backspace. It means suppose entering string you wrote "appke", but you want to write "apple " you can press backspace(until you haven't pressed enter). Now, what happens you take input with cin as you give input and press Enter for the next input. Like in your case you pressed "y" and then enter(which is denoted by "\n"). So as enter data it goes into the buffer and then you press enter that enter also goes into buffer but system picks only data from buffer like "y" in your case. So your buffer still has "\n" from previous data. Now come to getline. It has one parameter named "delim" [See-here]http://www.cplusplus.com/reference/string/string/getline/ who tells getline when to stop taking input. By default its values is "\n". Now from your previous entry, your buffer has already "\n" in it. So as getline comes in contact with the buffer, it sees "\n", and it thinks that data for input is present as he finds "\n" in the buffer which is the indicator when to stop. That's why it didn't ask for input. Now come to a solution. If ever you think to use getline after cin. All you need to do is to remove "\n" from the buffer. So all you do is cin.ignore("\n"). You are asking cin to ignore "\n" which was present in the buffer. So when control goes to getline. It ignores the already present "\n" in the buffer and works normally.

How can I pass parameters from a struct to a function correctly?

I would like the function dateCreate to pass the given parameters to the ones from the struct.
I have tried by having the Date d variable as a function parameter but it still shows me the error "field "day/month/year" could not be resolved".
struct Date{
int day;
int month;
int year;
} ;
Date dateCreate (int d, int m, int y){
Date d;
d.day =d;
d.month = m;
d.year =y;
return 0;
};
int main() {
int d,m,y;
cin << d << m << y;
cout << dateCreate(d,m,y); //Not completely sure if this is right either.
return 0;
}
I want the function to create a Date type of data from the integers given. Thank you very much.
dateCreate should return d, not 0.
For expression cout << dateCreate(d,m,y) to compile you need to implement std::ostream& operator<<(std::ostream&, Date const&).
Rather than a free function, I'd suggest you give your struct a constructor
struct Date{
Date(int _day, int _month, int _year)
: day(_day), month(_month), year(_year)
{ }
int day;
int month;
int year;
};
Then you can create this object like
int d,m,y;
cin >> d >> m >> y;
Date date(d, m, y);
To do something like
cout << date;
you'd need to overload operator<< for your Date struct
Equivalent code:
struct Date
{
int d;
int m;
int y;
};
int main()
{
int d = 1, m = 1, y = 1980;
std::cin >> d >> m >> y;
Date date{d, m, y}; // default constructor is called here
}
This said, because the problem you are solving is reading a date, you should probably implement it like this:
struct Date
{
int d;
int m;
int y;
};
std::istream& operator >>(std::istream& in, Date& d)
{
int d = 1, m = 1, y = 1980;
if(in >> d >> m >> y) // only set values if they were read successfully
d = Date{d, m, y};
return in;
}
Client code:
int main()
{
Date d{1, 1, 1980};
in >> d;
}
The most concise way to fix your snippet is providing an output operator for Date objects, e.g.
std::ostream& operator << (std::ostream& os, const Date& date)
{
return os << date.day << "/" << date.month << "/" << date.year;
}
then using the correct operators to read the user input
cin >> d >> m >> y;
and finally using the Date constructor generated by the compiler:
cout << Date{d, m, y};
You don't need a function creating a date object as long as you don't verify the input.
Note, however, that Date objects can now be in invalid states (negative day or month values etc.), so for future refinement, you should either implement a proper constructor that throws upon illegal input, or change the createDate function such that it e.g. returns a std::optional<Date> which is empty (std::nullopt) upon illegal input.

Asking for numbers using classes

The program should be like this:
1-ask for series and then parallel resistance (different classes)
2-pass Eq_R_Series and Eq_R_Paralel values(after they are calculated) to the Equivalent resistance that will calculate the Eq_R_Total
3-Display the Eq_R_Total.
so i need the main function and 3 classes(1 of the classes needs the info from the other 2).
class Serie
{
private:
int i, n = 4;
float R_Eq_S;
float r[4];
public:
float serie()
{
for (int i = 0; i < n; i++)
{
cout << "Resistence " << i + 1 << " ";
cin >> r[i];
R_Eq_S = R_Eq_S + r[i];
}
return R_Eq_S;
}
};
int main()
{
Serie s;
s.serie();
}
So i have the program with no errors now (doesn't mean theres nothing wrong), it runs and asks me to introduce the 1st resistence but after that it doesn't continue the cycle.
(i "just" need help to "link" the class to the main and the principal class.)
so this is my basic approach and it works but this is very limited, with a for i can change the number of resistance with one simple editing.
Thanks guys for the help even if it was just to point my mistakes ;) at least i think i'm learning
class Series
{
private:
float R1, R2, R3, R4;
public:
float R_Eq_S;
float series()
{
cout << "Resistance1= ";
cin >> R1;
cout << "Resistance2= ";
cin >> R2;
cout << "Resistance3= ";
cin >> R3;
cout << "Resistance4= ";
cin >> R4;
R_Eq_S = R1 + R2 + R3 + R4;
return R_Eq_S;
}
};
class Parallel{
private:
float R5, R6;
public:
float R_Eq_P;
float parallel(){
cout << "\nResistance5= ";
cin >> R5;
cout << "Resistance6= ";
cin >> R6;
R_Eq_P = (R5*R6) / (R5 + R6);
return R_Eq_P;
}
};
class Equivalent{
private:
float R_Eq;
public:
float r_eq()
{
Series s;
Parallel p;
R_Eq = s.series()+ p.parallel();
return R_Eq;
}
};
int main()
{
Equivalent r;
cout<<"\n\nR_Eq= "<<r.r_eq()<<endl;
}
#Tyler has pointed it in his comment. In your class definition r is declared as of type int. Then, in the expression r[i], i should be a pointer (this is usual C/C++ symmetry: a[i] is the same as *(a + i) so one of them should be dereferenceable, the other one being a number, but it does not matter much which one which). Your i is again an int nevertheless.
Second, I don't quite get how can your code compile, serie is a private method yet you call it outside of class's context.

Comparing smallest user input for C++

I tried to find the smallest number within 3 inputs. Here is my codes :
int main ()
{
double x = 4.0;
double y = 5.0;
double z = 3.0;
smallest(x,y,z);
cout << smallest << endl;
system("PAUSE");
}
double smallest(double x, double y, double z)
{
double smallest;
if ((x < y)||(x< z)) {
smallest = x;
} else if ((y < z)||(y < x)) {
smallest = y;
} else {
smallest = z;
}
return smallest;
}
However, I keep getting error. It stated that my smallest method in main method with undeclared identifier. This works when using eclipse but not visual studio. Can somebody explain to me why?
Thanks in advance.
Updated portion.
So I tried to do validation for this program. I want to ensure users only enter number and here are my codes :
double x, y, z;
bool correct_input = false;
do{
cout << "Enter first integer : " ;
cin >> x;
if(isdigit(x)){
correct_input = true;
}
}while(!correct_input);
do{
cout << "Enter second integer : ";
cin >> y;
if(isdigit(y)){
correct_input = true;
}
}while(!correct_input);
do{
cout << "Enter third integer : ";
cin >> z;
if(isdigit(z)){
correct_input = true;
}
}while(!correct_input);
cout << "Smallest integer is : " << smallest(x,y,z) << endl;
system("PAUSE");
When I entered alphabet or whatever except numbers, I get debug assertion failed. It does not prompt until user enter correct input. Can somebody help?
First of all, if you wish to use smallest() before it's defined, you need to prototype it. Add the following before main():
double smallest(double x, double y, double z);
Also, you are ignoring the return value of smallest(). Change
smallest(x,y,z);
cout << smallest << endl;
to
double smallest_val = smallest(x,y,z);
cout << smallest_val << endl;
This isn't the question you asked but your function is bugged because you confused || and &&.
Your function should be
double smallest(double x, double y, double z)
{
double smallest;
if (x < y && x < z)
smallest = x;
else if (y < z && y < x)
smallest = y;
else
smallest = z;
return smallest;
}
x is the smallest number if it is less y and it is less than z.
update
First thing to say is that if you want integers then you should be using int not double.
Second thing, isdigit doesn't do what you think it does. You've actually set yourself a very difficult problem. Here's one way to do it
#include <string> // for string class
bool correct_input = false;
do
{
cout << "Enter first integer : " ;
if (cin >> x)
{
correct_input = true;
}
else
{
// cin is in a error state after a failed read so clear it
cin.clear();
// ignore any remaining input to the end of the line
string garbage;
getline(cin, garbage);
}
}
while(!correct_input);
But this doesn't work perfectly. For instance if you enter abc then your program will ask for more input, but if you enter 123abc, then you will get the integer 123 even though 123abc is not a valid number.
If you really want to do this properly (and it is hard) then you must read in a string, check if the string could be converted to a number, if it can then do the conversion, if it can't then ask for more input.
Put this line above your main ;).
double smallest(double x, double y, double z);
You need to declare any function you make. This is called making a function header.
You should declare you function so that the compiler can recognize it.
Put its prototype above main function as this:
double smallest(double, double, double);
int main()
{
//Staff
}
There are two problem, here, one related to how to get the smallest, and the other related to ho get correct input.
For the first problem, let me propose a recursive approach:
// this is trivial
double smallest(double x, double y)
{ return (x<y)? x: y; }
// the smalles of three is the smallest between the smallest of two and the third
double smallest(double x, double y, double z)
{ return smallest(smallest(x,y),z); }
For the second problem, you have the same problem for each of the variables, so let's make a function for it:
#include <iostream>
#include <limits>
#include <string>
double read(std::istream& s, std::ostream& o, const std::string& message)
{
for(;;) //stay here until kiked out
{
double d=0.; //just a safe value - no particular meaning
o << message << std::endl; // prompt the request
bool good(s >> d); //read a double and keep the state
if(!good) s.clear(); //if we failed to read, clean the stream state
//in any case, discard everything unread until the return.
s.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
if(good) return d; //if reading succeeded, return.
//overwise loop back
}
}
This is based on the fact the std::cin have a state that is set to "bad" is the input cannot be read in the given variable.
We just read, and, if it fails, redo again and again.
But fist we have to clear the state, so thet the input can be unlocked.
Independently og good an bad reading, we have then to discard everuthing "extra" that can be typed in the line (think to 123asdf: we successfully read 123, but we have to discard abc)
The the reading was successful we just return it, otherwise we loop over and over until we get it.
The program itself, at this point will reduce to:
int main()
{
double x = read(std::cin, std::cout, "Enter first value");
double y = read(std::cin, std::cout, "Enter second value");
double z = read(std::cin, std::cout, "Enter third value");
std::cout << "the smallest numer is: " << smallest(x,y,z) << std::endl;
return 0;
}
that can run this way:
Enter first value
7
Enter second value
5.2yyyy
Enter third value
sf3
Enter third value
455
the smallest numer is: 5.2
A more advanced technique can be transform the function into a manipulator class, like this:
class read_value
{
public:
read_value(double& d, const std::string& prompt_, std::ostream& out_ = std::cout)
:z(d), prompt(prompt_), outstream(out_)
{}
friend std::istream& operator>>(std::istream& s, const read_value& a)
{
for(;;)
{
a.outstream << a.prompt << std::endl; // prompt the request
bool good(s >> a.z); //read a double and keep the state
if(!good) s.clear(); //if we failed to read, cleanr the stream state
//in any case, discard everything unread until the return.
s.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
if(good) return s; //if reading succeeded, return.
//overwise loop back
}
}
private:
double& z;
std::string prompt;
std::ostream& outstream;
};
letting the program a more idiomatic form:
int main()
{
double x,y,z;
std::cin >>
read_value(x,"Enter first value") >>
read_value(y,"Enter second value") >>
read_value(z,"Enter third value");
std::cout << "the smallest numer is: " << smallest(x,y,z) << std::endl;
return 0;
}
Another point can be the fact the user can loop forever by never typing a good sequence.
We can fix a maximum attempt limit introducing a counter in the for loop, and setting the input to "failed" if the loop terminates without returning:
friend std::istream& operator>>(std::istream& s, const read_value& a)
{
for(int i=0; i<10; ++i)
{
... //same as before
}
return s; //s will be returned in failed state
}
And then checking in the main program:
int main()
{
double x,y,z;
std::cin >>
read_value(x,"Enter first value") >>
read_value(y,"Enter second value") >>
read_value(z,"Enter third value");
if(!std::cin)
{
std::cout << "bad input." << std::endl;
return -1; //report as "program failed"
}
std::cout << "the smallest numer is: " << smallest(x,y,z) << std::endl;
return 0; //succeeded
}
.