Why does C++ show the wrong number? - c++

I have a little calculation.
Right now I calculate p_o and the value I get is correct, but somehow p_TR, where it gets the value from, is shown wrong.
The values I get are:
p_o= 0.3067666187328126 (right)
p_TR= 6.94807050163253e-310 (wrong)
Like you can see close to the end of the code, it says:
p_o = p_TR
I compile the code on Opensuse in the shell withe the g++ command.
I read that floating point numbers vary in decimal points, but this is not the same I would say.
#include <iostream>
#include <iomanip>
#include <cmath>
using namespace std;
int main ()
{
//Header der angezeigt wird bei Pragrammstart
cout << "----------------------------------------------------------------------\n";
cout << "**********************************************************************\n";
cout << "----------------------------------------------------------------------\n";
cout << "===>Exakter\n";
cout << "======>Riemann\n";
cout << "=========>Loeser" << endl;
cout.flush();
//physikalische Groessen
const float k = 1.4; //isentropen Exponent
const float M = 28.9; //Molare Masse [g/kmol] des Fluids
const float R = 8314.51; //universelle Gaskonstante [J/(kmol*K)]
cout << "\nStoff-/Physikalische Groessen\n" << "k=" << k << "; M=" << M << "; R=" << R << endl;
//Anfangswerte Links
const float rho_L = 1; //Dichte [kg/m^3]
const float u_L = 0; //Geschwindigkeit [m/s]
const float p_L = 1; //Druck [Pa]
const double T_L = (p_L*M)/(R*rho_L); //Temperatur[K]
const double RmT_L = p_L/rho_L; //Zwischen Groesse fuer a_L
const double a_L = pow((k*(R/M)*T_L),(0.5)); //Schallgeschwindigkeit [m/s]
cout << "\nWerte auf der rechten Seite:\n" << "rho_L=" << rho_L << "; u_L=" << u_L << "; p_L=" << p_L << "; T_L=" << T_L << "; a_L=" << a_L << "; RmT_L=" << RmT_L << endl;
//Anfangswerte Rechts
const float rho_R = 0.125;
const int u_R = 0;
const float p_R = 0.1;
const double T_R = (p_R*M)/(R*rho_R);
const double RmT_R = p_R/rho_R; //Zwischen Groesse fuer a_R
const double a_R = pow((k*(R/M)*T_R),(0.5));
cout << "\nWerte auf der linken Seite:\n" << "rho_R=" << rho_R << "; u_R=" << u_R << "; p_R=" << p_R << "; T_R=" << T_R << "; a_R=" << a_R << "; RmT_R=" << RmT_R << endl;
//Allgemeine Anfangswerte
const float du = u_R-u_L; //Geschwindigkeitsdifferenz [m/s]
const double du_krit = ((2*a_L)/(k-1)) + ((2*a_R)/(k-1)); //kritische Geschwindigkeitsdifferenz [m/s] (positive Druck Bedingung)
const double TOL = 1e-6; //Toleranz fuer p*
cout << "\nWeitere Groessen:\n" << "du=" << du << "; du_krit=" << du_krit << "; TOL=" << TOL << endl;
cout.flush();
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//Variablen Iteration p*
//Berechnung des Schätzwertes
double p_o;
double p_TR;
if (p_L>0 & p_R>0)
{
const double p_TR = pow(((a_L + a_R - 0.5*(k-1)*du)/((a_L/(pow(p_L,((k-1)/(2*k)))))+(a_R/(pow(p_R,((k-1)/(2*k))))))),((2*k)/(k-1))); //Schaetzwert fuer p0[Pa] als annahme das man 2 Verduennungswellen hat
//const double p_o = max(TOL,p_TR); //erster Schaetzwert , genommen ist Druck fuer 2 Verduennungen
p_o = p_TR;
cout << "\nkein Vakuum am Anfang ===> p_TR" << endl;
}
else
{
const double p_o = 0.5*(p_L+p_R);
cout << "\n Vakuum am Anfang ===> arithmitische Mittel fuer p_o" << endl;
}
//Variablen fuer Iteration
int n = 1;
double p_n = p_o; //p fuer Iterationen
float CHA = 1;
//Hilfsvariablen zum einfacheren rechnen
const double AL = 2/((k+1)*rho_L);
const double AR = 2/((k+1)*rho_R);
const double BL = ((k-1)*p_L)/(k+1);
const double BR = ((k-1)*p_R)/(k+1);
cout << "\np_TR=" << std::setprecision(16)<< p_TR;
cout << "\nWerte fuer Iteration:" << "\np_o=" << std::setprecision(16) << p_o << "\nAL=" << AL << "; BL=" << BL << "\nAR=" << AR << "; BR=" << BR << endl;
cout.flush();

Because you are declaring p_TR two times in different scopes, so you basically have two different variables in two different scopes having the same name p_TR.
One is instanced in the main scope, the other is instanced in your if/else block.
Same problem with p_o in the else block.
Just remove the "const double" inside your if/else block, it should do the trick.
double p_o;
double p_TR;
if (p_L>0 & p_R>0)
{
p_TR = pow(((a_L + a_R - 0.5*(k-1)*du)/((a_L/(pow(p_L,((k-1)/(2*k)))))+(a_R/(pow(p_R,((k-1)/(2*k))))))),((2*k)/(k-1))); //Schaetzwert fuer p0[Pa] als annahme das man 2 Verduennungswellen hat
//const double p_o = max(TOL,p_TR); //erster Schaetzwert , genommen ist Druck fuer 2 Verduennungen
p_o = p_TR;
cout << "\nkein Vakuum am Anfang ===> p_TR" << endl;
}
else
{
p_o = 0.5*(p_L+p_R);
cout << "\n Vakuum am Anfang ===> arithmitische Mittel fuer p_o" << endl;
}

Related

Receiving errors for default constructors

We are instructed to write the Frac.h and Frac.cpp files given a driver program. The purpose is to build a class for Fraction ADT to perform arithmetic with fractions. I have written the following files but am receiving some compiler errors.
C2512 'Fraction': no appropriate default constructor available
C2665 'Fraction::Fraction': no overloaded function could convert all the argument types
Driver file (Professor wrote this):
// driver for cmpsc122 Lab 4
#include "Frac.h"
#include <iostream>
using namespace std;
int main() {
Fraction x(-3, 8), y(-15, -20), z, w(5);
x.printFraction(); cout << " + "; y.printFraction();
z = x.add(y);
cout << " = "; z.printFraction(); cout << endl;
z.printFraction();
cout << " = "; z.printFractionAsFloat(); cout << endl << endl;
x.printFraction(); cout << " - "; y.printFraction();
z = x.subtract(y);
cout << " = "; z.printFraction(); cout << endl;
z.printFraction();
cout << " = "; z.printFractionAsFloat(); cout << endl << endl;
x.printFraction(); cout << " * "; y.printFraction();
z = x.multiply(y);
cout << " = "; z.printFraction(); cout << endl;
z.printFraction();
cout << " = "; z.printFractionAsFloat(); cout << endl << endl;
x.printFraction(); cout << " / "; y.printFraction();
z = x.divide(y);
cout << " = "; z.printFraction(); cout << endl;
z.printFraction();
cout << " = "; z.printFractionAsFloat(); cout << endl;
#ifdef _WIN32 // _WIN32 is used by Visual C++
#if (_MSC_VER <= 1916) // check if it Visual Studio 2017 or earlier
system("pause");
#endif
#endif
return 0;
}
/Sample run:
-3/8 + 3/4 = 3/8
3/8 = 0.375
-3/8 - 3/4 = -9/8
-9/8 = -1.125
-3/8 3/4 = -9/32
-9/32 = -0.28125
-3/8 / 3/4 = -1/2
-1/2 = -0.5
Press any key to continue . . .
*/
Frac.cpp (I wrote this)
#include "Frac.h"
#include <iostream>
#include <iomanip>
using namespace std;
Fraction Fraction::add(Fraction myFrac)
{
int newNum;
int newDom;
newNum = myFrac.num + num;
newDom = myFrac.dom + dom;
Fraction i(newNum, newDom);
return i;
}
Fraction Fraction::subtract(Fraction myFrac)
{
int newNum;
int newDom;
newNum = num - myFrac.num;
newDom = dom - myFrac.dom;
Fraction i(newNum, newDom);
return i;
}
Fraction Fraction::multiply(Fraction myFrac)
{
int newNum;
int newDom;
newNum = num * myFrac.num;
newDom = dom * myFrac.dom;
Fraction i(newNum, newDom);
return i;
}
Fraction Fraction::divide(Fraction myFrac)
{
int newNum;
int newDom;
newNum = num / myFrac.num;
newDom = dom / myFrac.dom;
Fraction i(newNum, newDom);
return i;
}
void Fraction :: printFraction()
{
cout << num << "/" << dom;
}
void Fraction::printFractionAsFloat()
{
float i = float(num) / float(dom);
cout << fixed << setprecision(3);
cout << i;
}`
Frac.h (and this)
#ifndef FRAC_H
#define FRAC_H
class Fraction
{
public:
Fraction(int myNum, int myDom);
Fraction add(Fraction myFrac);
Fraction subtract(Fraction myFrac);
Fraction multiply(Fraction myFrac);
Fraction divide(Fraction myFrac);
void printFraction();
void printFractionAsFloat();
private:
int num;
int dom;
};
#endif
I have tried creating a default constructor but all my attempts have just created more errors.

I get the error "free(): double free detected in tcache 2" while reading a file

When I try to compile my code in any IDE different than Visual Studio Code, I get the following error right after reading the file:
free(): double free detected in tcache 2.
When I delete the destructor, the program runs well, but the 'sort' function outputs all the lines as [(0,0),(0,0)]. I don't know why this happens. As mentioned, in Visual Studio Code, the program runs well from the beginning. Is there any solution to this problem? Am I missing anything?
Here are my codes and the files I am using:
main.cpp
#include <fstream>
#include <iostream>
#include <algorithm>
#include <vector>
#include <cassert>
#include <iomanip>
#include "Line.hpp"
#include "Point.hpp"
using namespace std;
void inputLines(string filename, vector <Line>& Lines){
ifstream inFS;
inFS.open(filename);
// checking if opened
if (!inFS.is_open()){
cout << "Couldn't open the input file" << endl << endl;
return;
}
//lines:
char letter1, letter2, letter3, letter4, letter5, letter6, d1;
inFS >> letter1 >> letter2 >> letter3 >> letter4 >> letter5 >> letter6>> d1;
//{[line1:[102.0,0.9],[97.0,1.0]],
char d2, letterl, letteri, lettern, lettere, letter_1, d3, d4,d5 ,d6 ,d7 ,d8 ,d9 ,d10 ,d11 ,d12;
double linep1x, linep1y, linep2x, linep2y;
while (!inFS.eof()){
inFS >> d2 >> letterl >> letteri >> lettern >> lettere >> letter_1 >> d3 >> d4
>> linep1x >> d5 >> linep1y >> d6 >> d7 >> d8 >> linep2x >> d9 >> linep2y >> d10 >> d11 >> d12;
if(!inFS.fail() && d2 == '[' && letterl == 'l' && letteri == 'i' && lettern == 'n' && lettere == 'e' && d3 == ':' && d4 == '[' && d5 == ','
&& d6 == ']' && d7 == ',' && d8 == '[' && d9 == ',' && d10== ']' && d11 == ']' ){
Lines.push_back(Line(linep1x,linep1y,linep2x,linep2y));
}
}
inFS.close();
}
bool parallel(Line& line1, Line& line2){
double slope1 = line1.getSlope();
double slope2 = line2.getSlope();
if(slope1 == slope2){
return true;
}
return false;
}
int main (){
cout <<"\n-----------------------------------------------\n"<< " Starting unit testing ... " << "\n-----------------------------------------------\n\n";
//----------------------------------------------------------------------------------------------------------------------------------------
cout << " ---------- | Testing setters and getters functions: | ----------\n\n";
Line l1_setGet;
cout << "We want to set a line with the coordinates (1,1)(2,2) and set the slope as 1.0 and the length as 1.41 \n\n";
Point p1_setGet(1,1);
Point p2_setGet(2,2);
l1_setGet.setPoint_1(p1_setGet);
l1_setGet.setPoint_2(p2_setGet);
l1_setGet.setSlope(1);
l1_setGet.setLength(1.41);
assert(l1_setGet.getLength() == 1.41);
assert(l1_setGet.getSlope() == 1);
cout << "All test passed...\n\n";
cout << "Line: " ; l1_setGet.print() ; cout << "\nSlope: " << l1_setGet.getSlope() << "\nLength: " << l1_setGet.getLength() <<"\n\n";
//----------------------------------------------------------------------------------------------------------------------------------------
cout << " ---------- | Testing null constructors and assigning constructor: | ----------\n\n";
Point p1_constructor(-32.4,22.4);
Point p2_constructor(44.2,-31.9);
Line l1_constructor;
Line l2_constructor(p1_constructor, p2_constructor);
cout << "We want the first line to be initialized by the null constructor and the second line to be set by the other constructor \n\n";
cout << "Line 1: \n ";
l1_constructor.print(); cout << "\n\n";
cout << "Line 2: [initialized with (-32.4,22.4) and (44.2, -31.9)] \n ";
l2_constructor.print(); cout << "\n\n";
cout << "Let's also test how the constructor calculates the length and the slope. For the second line the slope would be (-0.7) and the length would be (93.9):\n\n";
cout << "Slope: " << l2_constructor.getSlope() << "\n";
cout << "Length: " << l2_constructor.getLength() << "\n\n";
//----------------------------------------------------------------------------------------------------------------------------------------
cout << " ---------- | Testing copy constructor and copy assignment operator: | ----------\n\n";
Point p1_copy(27.2,-29.3);
Point p2_copy(45.2, 11.9);
cout << "These are our test cases: \n\n";
Line l1_copy(p1_copy, p2_copy);
Line l3_copy;
cout << " Line 1: "; l1_copy.print(); cout << "\n";
cout << " Line 3: "; l3_copy.print(); cout << "\n\n";
cout << "Let's create and initialize the second line with the first line to test the copy constructor:\n\n";
Line l2_copy(l1_copy);
cout << " Line 2: "; l2_copy.print() ; cout << "\n\n";
cout << "Let's now use the assignment operator (=) to assign the second line to the third line:\n\n";
l3_copy = l2_copy;
cout << " Line 3: "; l3_copy.print() ; cout << "\n\n";
//----------------------------------------------------------------------------------------------------------------------------------------
cout << " ---------- | Testing the parallel function: | ----------\n\n";
Point p1_para(2.0, 46.4);
Point p2_para(4.0, 88.8);
Point p3_para(2.0, 52.4);
Point p4_para(4.0, 94.8);
Point p5_para(2.0, -32.4);
Point p6_para(4.0, -74.8);
cout << "These are our test cases: \n\n";
Line l1_para(p1_para,p2_para);
Line l2_para(p3_para,p4_para);
Line l3_para(p5_para,p6_para);
cout << " Line 1'slope: " << l1_para.getSlope(); cout << "\n";
cout << " Line 2'slope: " << l2_para.getSlope(); cout << "\n";
cout << " Line 3'slope: " << l3_para.getSlope(); cout << "\n\n";
cout << "Two lines are parallel when they have the same slope. Let's test the parallel function:\n\n";
cout << "Let's see if Line 1 and Line 2 are parallel: \n\n";
parallel(l1_para,l2_para) == 1 ? cout << "They are parallel\n\n" : cout << "They are not parallel\n\n";
assert(parallel(l1_para,l2_para) == 1);
cout << "Let's see if Line 1 and Line 3 are parallel: \n\n";
parallel(l1_para,l3_para) == 1 ? cout << "They are parallel\n\n" : cout << "They are not parallel\n\n";
assert(parallel(l1_para,l3_para) == 0);
cout << "All tests passed...\n\n";
//----------------------------------------------------------------------------------------------------------------------------------------
cout << " ---------- | Testing the overloaded operators (< > ==): | ----------\n\n";
Point p1_oper(2, 2);
Point p2_oper(4, 4);
Point p3_oper(2, 2);
Point p4_oper(5, 5);
Point p5_oper(2, 2);
Point p6_oper(5, 5);
Point p7_oper(2, 2);
Point p8_oper(6, 6);
cout << "These are our test cases: \n\n";
Line l1_oper(p1_oper,p2_oper);
Line l2_oper(p3_oper,p4_oper);
Line l3_oper(p5_oper,p6_oper);
Line l4_oper(p7_oper,p8_oper);
cout << " Line 1: " ; l1_oper.print(); cout << " Length; " << l1_oper.getLength() <<"\n";
cout << " Line 2: " ; l2_oper.print(); cout << " Length; " << l2_oper.getLength() <<"\n";
cout << " Line 3: " ; l3_oper.print(); cout << " Length; " << l3_oper.getLength() <<"\n";
cout << " Line 4: " ; l4_oper.print(); cout << " Length; " << l4_oper.getLength() <<"\n\n";
cout << " Let's test (<): \n\n";
cout << "(Line 1 < Line 2): ";
l1_oper < l2_oper == true ? cout << "True\n\n" : cout << "False\n\n";
assert( l1_oper < l2_oper == true );
cout << "(Line 2 < Line 1): ";
l2_oper < l1_oper == true ? cout << "True\n\n" : cout << "False\n\n";
assert( l2_oper < l1_oper == false );
//----------------------------------------------------------------------------------------------------------------------------------------
cout << " Let's test (>): \n\n";
cout << "(Line 2 > Line 3): ";
l2_oper > l3_oper == true ? cout << "True\n\n" : cout << "False\n\n";
assert( l2_oper > l3_oper == false );
cout << "(Line 4 > Line 1): ";
l4_oper > l1_oper == true ? cout << "True\n\n" : cout << "False\n\n";
assert( l4_oper > l1_oper == true );
//----------------------------------------------------------------------------------------------------------------------------------------
cout << " Let's test (==): \n\n";
cout << "(Line 2 == Line 3): ";
l2_oper == l3_oper == true ? cout << "True\n\n" : cout << "False\n\n";
assert( l2_oper == l3_oper == true );
cout << "(Line 1 == Line 4): ";
l1_oper == l4_oper == true ? cout << "True\n\n" : cout << "False\n\n";
assert( l1_oper == l4_oper == false );
//----------------------------------------------------------------------------------------------------------------------------------------
cout << "All tests passed...\n\n";
cout << " ---------- | Testing the file reader function: | ----------\n\n"; //--------------------------------------------------------------------
vector <Line> Lines;
string filename = "lines.txt";
cout << "Reading file...\n\n";
inputLines(filename, Lines);
cout << "Outputting extracted coordinates out of the file: \n\n";
for (int i = 0 ; i < Lines.size() ; i++){
Lines.at(i).print();
cout << endl;
}
cout << endl;
cout << " ---------- | Testing the sort function: | ----------\n\n"; //--------------------------------------------------------------------
Lines.clear();
string filename_2 = "lines_2.txt";
cout << "Reading file with non-sorted values...\n\n";
inputLines(filename_2, Lines);
cout << "Outputting extracted coordinates out of the file: \n\n";
for (int i = 0 ; i < Lines.size() ; i++){
Lines.at(i).print();
cout << endl;
}
cout << endl;
cout << "Sorting... \n\n";
sort(Lines.begin(), Lines.end());
cout << "Outputting sorted values: \n\n";
for (int i = 0 ; i < Lines.size() ; i++){
Lines.at(i).print();
cout << endl;
}
cout << endl;
//----------------------------------------------------------------------------------------------------------------------------------------
Line l1_cout(1,2,3,4);
cout << "Overloading \"cout\" to print an object (in this case, a line with the coordinates (1,2),(3,4): \n\n";
cout << l1_cout << endl;
cout << endl;
//----------------------------------------------------------------------------------------------------------------------------------------
cout << " ---------- | Testing the insertion operator (>> cin): | ----------\n\n";
Line l1_cin;
cout << "Enter a line in the format [(x1,y1),(x2,y2)] " << endl << endl;
cin >> l1_cin;
cout << "\nYou entered: " << endl << endl;
cout << "------- ";
l1_cin.print();
cout << " -------\n\n";
return 0;
}
Line.hpp
#include <cmath>
#include "Point.hpp"
#include <iomanip>
using namespace std;
#ifndef LINE_H
#define LINE_H
class Line{
private:
Point* p1;
Point* p2;
double slope;
double length;
public:
Line(); //null constructor
Line(Point p1, Point p2);
Line(double linep1x, double linep1y, double linep2x, double linep2y);
// !accessors and mutators
//---------------------------------------//
void setPoint_1 (double x, double y){
p1->setX(x);
p1->setY(y);
calculateLength();
calculateSlope();
}
void setPoint_1 (Point p){
*p1=p;
calculateLength();
calculateSlope();
}
Point getPoint_1() const{
return *p1;
}
//---------------------------------------//
void setPoint_2 (double x, double y){
p2->setX(x);
p2->setY(y);
calculateLength();
calculateSlope();
}
void setPoint_2 (Point p){
*p2=p;
calculateLength();
calculateSlope();
}
Point getPoint_2() const{
return *p2;
}
//---------------------------------------//
void setSlope(double s){
this->slope = s;
}
void calculateSlope(){
slope = ( (p2->getY()) - (p1->getY()) ) / ((p2->getX()) - (p1->getX()) );
}
double getSlope() const{
return this->slope;
}
//---------------------------------------//
void setLength(double l){
this->length = l;
}
void calculateLength(){
length = sqrt( (pow( ( (p2->getX()) - (p1->getX()) ) , 2) ) + (pow(( (p2->getY()) - (p1->getY())), 2 ) ) );
}
double getLength() const{
return this->length;
}
//---------------------------------------//
//!print
void print() const;
//!destructor
~Line();
//!copy constructor
Line(const Line& l);
//!assignment
Line& operator=(const Line& line);
//! overloading operators
bool operator==(const Line& line);
bool operator<(const Line& line);
bool operator>(const Line& line);
friend ostream& operator<<(ostream& out, Line& L);
friend istream& operator>>(istream& in, Line& L);
};
#endif
Line::Line(){ //*null constructor
slope = 0;
length= 0;
p1 = new Point();
p2 = new Point();
}
Line::Line(double linep1x, double linep1y, double linep2x, double linep2y){
p1 = new Point ;
p2 = new Point ;
p1->setX(linep1x);
p1->setY(linep1y);
p2->setX(linep2x);
p2->setY(linep2y);
//The distance between two points is given by d(P, Q) = √(x2 − x1)² + (y2 − y1)²
calculateLength();
//The slope of a line, given two points, is defined as m = (y2-y1)/(x2-x1)
calculateSlope();
}
Line::Line(Point point1, Point point2){ //*overload constructor to calculate length and slope
double x1 = point1.getX();
double y1 = point1.getY();
double x2 = point2.getX();
double y2 = point2.getY();
p1 = new Point(x1,y1);
p2 = new Point(x2,y2);
//The distance between two points is given by d(P, Q) = √(x2 − x1)² + (y2 − y1)²
calculateLength();
//The slope of a line, given two points, is defined as m = (y2-y1)/(x2-x1)
calculateSlope();
}
//*destructor
Line::~Line(){
delete p1;
delete p2;
}
//*copy constructor
Line::Line(const Line& line){
this->p1 = new Point ;
this->p2 = new Point ;
this->p1 = line.p1;
this->p2 = line.p2;
length = line.length;
slope = line.slope;
}
//*assignment operator
Line& Line::operator=(const Line& line){
if(this!=&line){
delete this->p1;
delete this->p2;
this->p1 = new Point ;
this->p2 = new Point ;
this->p1 = line.p1;
this->p2 = line.p2;
}
return *this;
}
// * =
bool Line::operator==(const Line& line){
if(this->length == line.length){
return true;
}
return false;
}
//* < operator
bool Line::operator<(const Line& line){
if(this->length < line.length){
return true;
}
return false;
}
//* > operator
bool Line::operator>(const Line& line){
return (!(this->length < line.length) && !(this->length == line.length));
}
// * << operator (cout)
ostream& operator<<(ostream& out, Line& L){
out << "[(" << (L.p1->getX()) << ", " << (L.p1->getY()) <<"), (" << L.p2->getX() << ", " << (L.p2->getY()) <<")]";
return out;
}
// * >> operator (cin)
istream& operator>>(istream& in, Line& L){
char d1, d2, d3, d4, d5, d6, d7, d8, d9;
double x1, y1, x2, y2;
//[(x1,y1),(x2,y2)]
in >> d1 >> d2 >> x1 >> d3 >> y1 >> d4 >> d5 >> d6 >> x2 >> d7 >> y2 >> d8 >> d9;
if(!(d1 == '[' && d2 == '(' && d3 == ',' && d4 == ')' && d5 == ',' && d6 == '(' && d7 == ',' && d8 == ')' && d9 == ']' )){
cout << "Invalid format" << endl;
}
else{
L.setPoint_1(x1,y1);
L.setPoint_2(x2, y2);
}
return in;
}
//* print function
void Line::print() const{
cout << fixed << setprecision (1) << "[" << "(" << p1->getX() <<", " << p1->getY() << ")" << "," << "(" << p2->getX() << ", " << p2->getY() << ")" << "]" ;
}
Point.hpp
#include <cmath>
#include <string>
using namespace std;
#ifndef POINT_H
#define POINT_H
class Point{
private: // can only be used by public
double x;
double y;
public:
///constructor
Point (double X=0, double Y=0) : x(X), y(Y) {}
//functions
void setX(double x) {this->x= x ;}
double getX() const {return this->x ;}
void setY(double y) {this->y=y ;}
double getY() const {return this->y ;}
void print() const;
friend bool operator== (Point lhp, Point rhp);
friend bool operator> (Point lhp, Point rhp);
friend bool operator< (Point lhp, Point rhp);
};
void Point::print() const{
cout << "(" << this->x<< ","<<this->y<<")" << endl;
}
bool operator== (Point lhp, Point rhp){
if((lhp.x == rhp.x && lhp.y == rhp.y)){
return true;
}
else{
return false;
}
}
bool operator> (Point lhp, Point rhp){
int euclideanLeft, euclideanRight;
euclideanLeft = sqrt((pow(lhp.x, 2))+(pow(lhp.y,2)));
euclideanRight = sqrt((pow(rhp.x, 2))+(pow(rhp.y,2)));
if((euclideanLeft > euclideanRight)){
return true;
}
else{
return false;
}
}
bool operator< (Point lhp, Point rhp){
return !((lhp.x > rhp.x, lhp.y > rhp.y) || (lhp.x == rhp.x, lhp.y == rhp.y));
}
#endif
lines.txt
lines:
{
[line1:[102.0,0.9],[97.0,1.0]],
[line2:[103.0,0.8],[98.0,1.0]],
[line3:[104.0,0.7],[99.0,1.0]],
[line4:[105.0,0.6],[100.0,1.0]]
}
lines_2.txt
lines:
{
[line2:[103.0,0.8],[98.0,1.0]],
[line1:[102.0,0.9],[97.0,1.0]],
[line4:[105.0,0.6],[100.0,1.0]],
[line3:[104.0,0.7],[99.0,1.0]]
}
Ignoring the fact that there is no real reason why Line is keeping pointers to Points....
Your copy constructor is only doing a shallow copy which means you end up with multiple Line instances pointing to the same points:
Line::Line(const Line& line){
this->p1 = new Point ;
this->p2 = new Point ;
this->p1 = line.p1; // this overwrites the newly allocated
this->p2 = line.p2; // p1 and p2 above.
length = line.length;
slope = line.slope;
}
Should be something like:
Line::Line(const Line& line){
this->p1 = new Point(line.p1->getX(), line.p1->getY());
this->p2 = new Point(line.p2->getX(), line.p2->getY());
length = line.length;
slope = line.slope;
}
If this is not for some class that requires the Points in Line to be pointers I would really recommend you consider just storing the Points in the lines. It will solve a lot of headaches.

Having difficulty creating operator overload for class module using literal string as argument

I am relatively new to C++. I am hoping to get assistance creating an overload operator that will permit me to use a literal string with a class I am writing. This project is for learning.
I created a custom Date class (and have not worried about the actual logic in the class; I'm just trying to get the interface working and to understand where my roadblock is.
It may not look like it, but I have put in a lot of time on this, so an explanation designed for a beginning c++ progammer would be very helpful to me and anyone who follows in my footsteps.
Basically, I'd like to be able to do this with my class:
Date dt(5,6,92);//create class object
int myint;
myint = dt;//this works
string mystr;
mystr = dt("mm/dd/yy");//this does not compile
Thanks in advance. (A compilable test program shown below)
#include <iostream>
#include <string>
#include <windows.h>
using namespace std;
class Date
{
int mo, da, yr;
public:
Date(int m, int d, int y)
{
cout << "Constructor int m, int d, int y called " << endl;
mo = m; da = d; yr = y;
}
string getdatestr(const char *s = "") {//user sends in format "d2/" "mm/dd/yy" etc
cout << "getdatestr const char *s called mo = " << mo << " da = " << da << "yr = " << yr << endl;
return to_string(mo) + "/" + to_string(da) + "/" + to_string(yr);
}
int getdate(){
cout << "getdate int t called" << endl;
string tag;
tag = to_string(yr) + to_string(mo) + to_string(da);
return stoi(tag);
}
string getdate(string &str){
cout << "getdate with string as ref" << endl;
return "5/5/55";
}
int getdate(int &myint){
cout << "getdate with int as ref" << endl;
return 12345;
}
void setdate(string dt){
cout << "setdate string dt called " << dt << endl;
mo = 1;
da = 2;
yr = 2020;
}
void setdate(int intdte){
cout << "setdate int to " << intdte << endl;
mo = 99;//any int for now
da = 98;
yr = 1997;
}
void setdate(const char *dte){
cout << "setdate char* dte = " << dte << endl;
mo = 94;
da = 95;
yr = 1996;
}
~Date(){
cout << "destructor called" << endl;
}
//below code permits this in main(): myint = dt;
operator int() {
cout << "operator int()" << endl;
string tag;
tag = to_string(yr) + to_string(mo) + to_string(da);
return stoi(tag);
}
//end section to permit: myint = dt;
//what do I need so I can do this: mystr = dt("mm/dd/yy");, nothing below worked; I tried many more iterations
//than what are shown here
/*
operator string() {
cout << "operator string char" << endl;
return "hello world";
}
string operator = (string &rhs){
cout << "string" << endl;
return "return a string";
}
operator = (const string &rhs){
cout << "will this work?" << endl;
return *this;
}
char& operator = (char(&)[9]){
cout << "whoa, it worked" << endl;
//return "got it";
}
operator = (char*){
cout << "try again" << endl;
}
string operator const char(&)[9] {
cout << "one more time" << endl;
string *ptr;
ptr = "one more time";
return ptr;
}
//end nothing worked to permit me to do this mystr = dte("mm/dd/yy"); section
*/
};//end of class
int main()
{
//create a Date class object dt
Date dt(5, 6, 92);
dt.setdate("02/15/22");
cout << endl;
cout << "next two mystr messages return null because I " << endl;
cout << "can't seem to write a valid overload operator for a literal string" << endl;
string mystr;
//mystr = dt("mm/dd/yy");//does not compile (no match for call to '(Date) (const char [9])'
cout << "mystr using dt(str) = " << mystr << endl;
string myconv = "mm/dd/yy";
//mystr = dt(myconv);//does not compile (no match for call to '(Date) (std::__cxx11::string&)'
cout << "mystr using dt(mm//dd//yy) = " << mystr << endl;
cout << endl;
//this section works
//can I assign dt to an integer (as #days from a reference date)
cout << "this section seems to work" << endl;
int myint;
cout << "myint = dt;" << endl;
myint = dt;//does not compile
cout << "myint (using = dt;) = " << myint << endl;
cout << endl;
system("pause");
}

Transform c++ class private variables to public

I am a first year student of programming, and I need some help.
I have code with public class but I need to change public to private. And it doesn't work for me. Maybe somebody can help me with some suggestions? Here's my working code with public objects, but I need to private. How can I do that?
This is my class's files:
Klientas.h:
#include <iostream>
#include <fstream>
#include <string>
#include <cmath>
#include <iomanip>
using namespace std;
class Klientas
{
public:
string vardas;
double lesos;
};
#include <iostream>
#include <fstream>
#include <string>
#include <cmath>
#include <iomanip>
using namespace std;
Klipas.h :
class Klipas
{
public:
string produktas;
string grupe;
double trukme;
double krastine1;
double krastine2;
double plotas;
double klipoSekKaina;
double klipoKaina;
};
My code:
Lab_1.cpp
#include "Klipas.h"
#include "Klientas.h"
using namespace std;
//---------------------------------------------
int main() {
setlocale(LC_ALL, "Lithuanian");
Klipas K[100];
int na;
Klientas kl;
// Iš failo fv įveda duomenis į objektų masyvą K(kiek).
ĮvestiDuomenis("Duomenys.txt", K, na);
SpausdintiDuomenis("Rezultatai.txt", K, na);
}
void ĮvestiDuomenis(string fv, Klipas K[], int & kiek) {
ifstream fd ("Duomenys.txt");
fd >> kiek;
fd.ignore();
for (int i = 0; i < kiek; i++) {
getline(fd, K[i].produktas, ','); fd >> ws;
fd >> K[i].grupe;
fd >> K[i].trukme;
fd >> K[i].krastine1;
fd >> K[i].krastine2;
fd >> K[i].klipoSekKaina;
fd.ignore();
}
fd.close();
// cout << "Programa baigė darbą\n";
}
// Objektų masyvo K(kiek) reikšmes spausdina lentele į failą fv
void SpausdintiDuomenis(string fv, Klipas K[], int kiek) {
ofstream fr("Rezultatai.txt", ios::app);
fr.setf(ios::fixed); fr.setf(ios::left);
cout << "Klipų skaičius: " << kiek << endl;
cout << "Klipų sąrašas:\n";
cout << "----------------------------------------------------\n";
cout << "| Produktas | Grupė | Klipo trukmė(s) | 1 Kraštinė(cm) | 2 Kraštinė(cm) | Klipo sekundės kaina(Eur/s) | \n";
cout << "----------------------------------------------------\n";
for (int i = 0; i < kiek; i++) {
cout << "| " << setw(10) << K[i].produktas << "| " << K[i].grupe
<< setprecision(0) << setw(10) << "| " << K[i].trukme << "| " << setw(15) << K[i].krastine1 << "| " << setw(10) << K[i].krastine2 << "| " << setw(10) << K[i].klipoSekKaina << endl;
}
{
cout << "-------------------------------\n";
cout << "Klipo Kava plotas:" << K[0].krastine1*K[0].krastine2 << " " << "cm2" << endl;
cout << "Klipo Obuolys plotas:" << K[1].krastine1*K[1].krastine2 << " " << "cm2" << endl;
cout << "Klipo Sultys plotas:" << K[2].krastine1*K[2].krastine2 << " " << "cm2" << endl;
cout << "-------------------------------\n";
}
string ilg_trukme; // randame kuris klipas yra ilgiausias
if (K[0].trukme > K[1].trukme) {
ilg_trukme = K[0].produktas;
} else if (K[1].trukme > K[2].trukme) {
ilg_trukme = K[1].produktas;
} else {
ilg_trukme = K[2].produktas;
}
cout << "Ilgiausias klipas: " << ilg_trukme << endl;
cout << "-------------------------------\n";
{
K[0].klipoKaina = K[0].trukme * K[0].klipoSekKaina;
K[1].klipoKaina = K[1].trukme * K[1].klipoSekKaina;
K[2].klipoKaina = K[2].trukme * K[2].klipoSekKaina;
cout << "Klipo Kava Kaina:" << K[0].klipoKaina << " " << "Eur." << endl;
cout << "Klipo Obuolys Kaina:" << K[1].klipoKaina << " " << "Eur." << endl;
cout << "Klipo Sultys Kaina:" << K[2].klipoKaina << " " << "Eur." << endl;
cout << "-------------------------------\n";
}
{
string brangiausias_klipas; //randame kuris klipas brangiausias
double br_kl;
Klientas kl;
if (K[0].klipoKaina > K[1].klipoKaina && K[0].klipoKaina > K[2].klipoKaina ) {
brangiausias_klipas = K[0].produktas;
br_kl = K[0].klipoKaina;
} else if (K[1].klipoKaina > K[2].klipoKaina) {
brangiausias_klipas = K[1].produktas;
br_kl = K[1].klipoKaina;
} else {
brangiausias_klipas = K[2].produktas;
br_kl = K[2].klipoKaina;
}
cout << "Brangiausias klipas yra: " << brangiausias_klipas << endl;
cout << "-------------------------------\n";
cout << "Kiek jūs turite pinigų? " << endl; //kliento turimos pajamos
cin >> kl.lesos ;
cout << "-------------------------------\n";
//Randame kuriuos klipus klientas glaėtų įsigyti su savo pajamom
{
if(kl.lesos < K[0].klipoKaina && kl.lesos < K[1].klipoKaina && kl.lesos < K[2].klipoKaina) {
cout << "Jūs negalite nusipikrti nei vieno klipo " << endl;
} else {
if(kl.lesos >= K[0].klipoKaina) {
cout << "Jūs galite nusipirkti klipą " << K[0].produktas << endl;
}
if (kl.lesos >= K[1].klipoKaina) {
cout << "Jūs galite nusipirkti klipą " << K[1].produktas << endl;
}
if (kl.lesos >= K[2].klipoKaina) {
cout << "Jūs galite nusipirkti klipą " << K[2].produktas << endl;
}
}
}
}
}
Your teacher probably wants you to use getters.
In:
class Klipas
{
public:
string produktas;
string grupe;
double trukme;
double krastine1;
double krastine2;
double plotas;
double klipoSekKaina;
double klipoKaina;
};
You want to have access to all these members, but prevent external changes.
So you can change your code to:
class Klipas
{
public:
string GetProduktas() {return produktas;}
string Getgrupe() {return grupe;}
double Gettrukme() {return trukme;}
double Getkrastine1() {return krastine1;}
double Getkrastine2() {return krastine2;}
double Getplotas() {return plotas;}
double GetklipoSekKaina(){return klipoSekKaina;}
double GetklipoKaina() {return klipoKaina;}
private:
string produktas;
string grupe;
double trukme;
double krastine1;
double krastine2;
double plotas;
double klipoSekKaina;
double klipoKaina;
};
and use those getters instead of the objects themselves in your function:
fd >> K[i].Getgrupe();
fd >> K[i].Gettrukme();
fd >> K[i].Getkrastine1();
fd >> K[i].Getkrastine2();
fd >> K[i].GetklipoKaina();
As for setters go, you can either set your values in the constructor, or implement the same way:
public:
void SetProduktas(string prdkt) {produktas = prdkt;}
You can rewrite your class variables to be private and then use getters and setters to modify them.
class C {
private:
int id;
public:
int get_id() { return this->id; }
void set_id(int newId) { this->id = newId; }
};
Or you can make private class inside of another class
class A {
private:
class D {};
};

comparing characters in c++

If I run my program, it doesn't compare the value entered after "Bitte Funktion waehlen" to sin, cos or tan. Instead, it always jumps directly to the else statement.
#include <iostream>
#include <string>
using namespace::std;
int funktions_wahl(char funktion, int genauigkeit)
{
char sin;
char cos;
char tan;
int x;
if (funktion==sin) {
cout << "sin von " << x << " =" << 2*x*genauigkeit; //Wie sin als fkt hier benutzen? 2x vorübergehend.
}
else if (funktion==cos) {
cout << "cos von " << x << " =" << 4*x*genauigkeit; //Gleiches Spiel wie oben.
}
else if (funktion==tan) {
cout << "tan von " << x << " =" << 8*x*genauigkeit; //Gleiches Spiel wie oben;
}
else {
cout << "Keine gültige Variable eingegeben\r";
}
return 0;
}
int main() {
char f;
int g=0;
cout << "Taschenrechner 1.0\r" << "Bitte Funktion eingeben: ";
cin >> f;
cout << "Genauigkeit wählen: ";
cin >> g;
funktions_wahl(f, g);
}
I don't understand why. Does someone has an advice for me?
char sin;
char cos;
char tan;
int x;
if (funktion==sin) {
cout << "sin von " << x << " =" << 2*x*genauigkeit;
You forgot to initialize sin, cos, tan and x and are therefore reading uninitialized memory.
You probably intended something like char sin = 's'; and so on.
The problem is that you didn't initialize the variables sin, cos and tan (which should be constants actually), which leads to undefined behavior:
For a debug build, the compiler may indeed execute step-by-step your program, and thus compare uninitialized, random numbers;
For an optimized build, the compiler is likely to optimize away these comparisons between uninitialized local variables and only implement the error case (cout << "Keine gültige Variable eingegeben\r";).
To correct this, you should instead define and initialize these constants as follows:
const char sin = 's';
const char cos = 'c';
const char tan = 't';
UPDATE
To answer your updated question (how to consume "sin" rather than 's'), you simply need to change the types of your variables from char to string, and change the literals from char literals (between simple quotes) to string literals (between double quotes), as exemplified below:
string f;
...
const string sin = "sin";
const string cos = "cos";
const string tan = "tan";
Thanks for your answers.
I changed it as you suggested. But still isn´t it possible to enter e.G sin instead of s ?
#include <iostream>
#include <string>
using namespace::std;
int funktions_wahl(char funktion, int genauigkeit, int x)
{
char sin='s';
char cos='c';
char tan='t';
if (funktion==sin) {
cout << "sin von " << x << " =" << 2*x*genauigkeit << "\r"; //Wie sin als fkt hier benutzen? 2x vorübergehend.
}
else if (funktion==cos) {
cout << "cos von " << x << " =" << 4*x*genauigkeit << "\r"; //Gleiches Spiel wie oben.
}
else if (funktion==tan) {
cout << "tan von " << x << " =" << 8*x*genauigkeit << "\r"; //Gleiches Spiel wie oben;
}
else {
cout << "Keine gültige Variable eingegeben\r";
}
return 0;
}
int main() {
char f;
int g=0;
int x=0;
cout << "Taschenrechner 1.0\r" << "Bitte Funktion eingeben: ";
cin >> f;
cout << "Genauigkeit wählen: ";
cin >> g;
cout << "x wählen: ";
cin >> x;
funktions_wahl(f, g, x);