This is my main function
int main()
{
const string filename = "ass10data.txt"; // use your filename here
ifstream fin(filename.c_str());
if (!fin)
{
cerr << "Unable to open " << filename << endl;
exit(1);
}
string buffer;
Quadrilateral* ptrQuad;
while (getline(fin,buffer))
{
// Process only valid input
if (buffer.size() > 1)
{
ptrQuad = createQuadrilateralFromString(buffer);
cout << *ptrQuad << endl;
delete ptrQuad;
}
}
fin.close();
}
This is the overloaded insertion operator
ostream& operator<<(ostream&out, Quadrilateral *pointerQuad)
{
if (pointerQuad->getType() == "rectangle")
{
out << "Rectangle: sides " << pointerQuad->getFirst() << " and " << pointerQuad->getSecond() << " area=" << pointerQuad->area();
out << " perimeter=" << pointerQuad->perimeter();
return out;
}
else if(pointerQuad->getType() == "square")
{
out << "Square: side "<< pointerQuad->getFirst() << " area="<< pointerQuad->area();
out << " perimeter=" << pointerQuad->perimeter();
return out;
}
else if(pointerQuad->getType() == "parallelogram")
{
out << "Parallelogram: sides " << pointerQuad->getFirst() << " and " << pointerQuad->getSecond() << " area=" << pointerQuad->area();
out << " perimeter=" << pointerQuad->perimeter();
return out;
}
else if(pointerQuad->getType() == "rhombus")
{
out << "Rhombus: side "<< pointerQuad->getFirst() << " area="<< pointerQuad->area();
out << " perimeter=" << pointerQuad->perimeter();
return out;
}
else
return out;
}
I'm getting an error message saying "no match for 'operator<<' (operand types are 'std::ostream {aka std::basic_ostream}' and 'Quadrilateral')" and I can't figure out why.
The insertion operator should take a const reference to the Quadrilateral, not a pointer to it:
ostream& operator<<(ostream&out, Quadrilateral const &pointerQuad)
Of course, that means your function should use the value syntax, not the pointer one too.
if (pointerQuad.getType() == "rectangle")
{
out << "Rectangle: sides " << pointerQuad.getFirst() << " and " << pointerQuad.getSecond() << " area=" << pointerQuad.area();
out << " perimeter=" << pointerQuad.perimeter();
return out;
}
[...]
Related
I have class Date, functions bubbleSort, isAfter and printVector. So my task is: Use the function bubbleSort to sort vector type objects Date(using function isAfter which compares dates). I've done something but it doesn't works, so can anyone help me with this?
Function bubble sort(doesn't works with "Date", works fine with integers ,strings...).
Here is my code:
//isAfter
template<>
bool isAfter(const Date &first, const Date &second) {
if (first.getYear() == second.getYear()) {
if (first.getMonth() == second.getMonth()) {
if (first.getDay() == second.getDay()) {
cout << first.toString() << " is equal to " << second.toString() << endl;
return false;
} else if (first.getDay() > second.getDay()) {
cout << " " << first.toString() << " is after " << " " << second.toString() << endl;
return true;
} else if (first.getDay() < second.getDay()) {
cout << " " << second.toString() << " is after " << " " << first.toString() << endl;
return true;
}
} else if (first.getMonth() > second.getMonth()) {
cout << " " << first.toString() << " is after " << " " << second.toString() << endl;
return true;
} else if (first.getMonth() < second.getMonth()) {
cout << " " << second.toString() << " is after " << " " << first.toString() << endl;
return true;
}
} else if (first.getYear() > second.getYear()) {
cout << " " << first.toString() << " is after " << " " << second.toString() << endl;
return true;
} else if (first.getYear() < second.getYear()) {
cout << " " << second.toString() << " is after " << " " << first.toString() << endl;
return true;
}
return false;
}
//bubbleSort
template<typename T>
void bubbleSort(vector<T> &vec) {
bool swapp= true;
while (swapp) {
swapp= false;
for (unsigned int i = 0; i < vec.size()- 1; i++) {
if (vec[i] > vec[i + 1]) {
swap(vec[i], vec[i + 1]);
swapp = true;
}
}
}
}
so how can i add isAfter in bubbleSort to work fine with "Date" objects?
If this is always the sort order for dates and you control that type, you could implement the comparison operators operator<, operator>, operator<=, operator>=, operator== and operator!= for that type.
Otherwise, the conventional approach is to modify your sorting algorithm to accept a custom comparator (by convention, having the interface of operator<, which requires you to flip your comparison) from its callers, something like:
template <typename T, typename Compare>
void bubbleSort(vector<T> &vec, Compare compare) {
// as you currently have, but using compare(a, b) instead of a < b
}
template <typename T>
void bubbleSort(vector<T> &vec) {
bubbleSort(vec, std::less<>());
}
Then callers can use isAfter like this:
bubbleSort(dates, [](const Date& a, const Date& b) { return isAfter(b, a); });
I've recently started learning c++ and for the life of me, I can't seem to get the syntax of using ostream in a class and what arguments should I pass. Here's the code:
This is the class in question:
#include <iostream>
#include <string>
using namespace std;
class Pokemon{
friend ostream& operator<<(ostream&, Pokemon);
public:
string name, level, cp;
Pokemon(string x="Pikachu", string y="5", string z="1000"){
name = x;
level = y;
cp = z;
}
Pokemon name(){
return this->name;
}
Pokemon level(){
return this->level;
}
Pokemon cp(){
return this->cp;
}
Pokemon display_stats(){
cout << this-> name << "stats are:" << endl;
cout << " " << "Attack: 2716.05" << endl;
cout << " " << "Defence: 1629.63" << endl;
cout << " " << "HP: 1086.42" << endl;
}
};
template<typename TYPE> //i dont understand this and the things i've written down here are only based on samples i've seen
ostream& operator<<(ostream& os, Pokemon & c){
os << "The level of " << c.name << " is" << c.level << " with cp of " << c.cp;
}
As you could see, I already tried constructing the ostream thing but I don't really understand how it works. This is my main function:
int main()
{
Pokemon a, b, c, d;
a = Pokemon();
b = Pokemon("Weezing");
c = Pokemon("Nidoking", 100);
d = Pokemon("Mewtwo", 50, 5432.1);
cout << a << endl;
cout << b << endl;
cout << c << endl;
cout << d << endl;
cout << "Jessie: You are no match to me! Go " << b.name << "!" << endl;
cout << "Gary: Go lvl " << c.level << " " << c.name << "! Crush them" << endl;
cout << "Ash: " << a.name << " can do it even thouh he is only level " << a.level << endl;
cout << "Jessie: Hahaha! My " << b.name << " CP is " << b.cp << endl;
cout << "Gary: "<< c.name << " CP is " << c.cp << endl;
cout << "Ash: " << a.name << " CP is " << a.cp << endl;
cout << "Giovanni: Behold " << d.name << " is here." << endl;
d.display_stats();
return 0;
}
I'm getting errors of:
no instance of constructor "Pokemon::Pokemon" matches the argument list -- argument types are: (const char [9], int) //on line c = Pokemon("Nidoking", 100);
no instance of constructor "Pokemon::Pokemon" matches the argument list -- argument types are: (const char [7], int, double) //on line d = Pokemon("Mewtwo", 50, 5432.1);
All of your Pokemon class methods are returning the wrong type. And your main() is not calling any of the methods correctly at all.
Change your Pokemon class to look more like this:
#include <iostream>
#include <string>
using namespace std;
class Pokemon {
private:
string m_name;
int m_level;
double m_cp;
friend ostream& operator<<(ostream&, const Pokemon&);
public:
Pokemon(string x="Pikachu", int y=5, double z=1000) {
m_name = x;
m_level = y;
m_cp = z;
}
string name() const {
return m_name;
}
int level() const {
return m_level;
}
double cp() const {
return m_cp;
}
void display_stats() const {
cout << m_name << " stats are:" << endl;
cout << " " << "Attack: 2716.05" << endl;
cout << " " << "Defense: 1629.63" << endl;
cout << " " << "HP: 1086.42" << endl;
}
};
ostream& operator<<(ostream& os, const Pokemon &c) {
os << "The level of " << c.m_name << " is " << c.m_level << " with cp of " << c.m_cp;
return os;
}
And then change main() to look more like this:
int main()
{
Pokemon a;
Pokemon b("Weezing");
Pokemon c("Nidoking", 100);
Pokemon d("Mewtwo", 50, 5432.1);
cout << a << endl;
cout << b << endl;
cout << c << endl;
cout << d << endl;
cout << "Jessie: You are no match to me! Go " << b.name() << "!" << endl;
cout << "Gary: Go lvl " << c.level() << " " << c.name() << "! Crush them" << endl;
cout << "Ash: " << a.name() << " can do it even though he is only level " << a.level() << endl;
cout << "Jessie: Hahaha! My " << b.name() << " CP is " << b.cp() << endl;
cout << "Gary: " << c.name() << " CP is " << c.cp() << endl;
cout << "Ash: " << a.name() << " CP is " << a.cp() << endl;
cout << "Giovanni: Behold " << d.name() << " is here." << endl;
d.display_stats();
return 0;
}
Live Demo
Very new to programming.
This bit of my program accepts two strand of DNA as input and output them in a double helix drawing. The problem is, if one of the two input strand is longer than the other, i will receive error.
So I thought, is it possible that if strand[add] is non-existent anymore, replace it with *?
#include <iostream>
#include <string>
#include <conio.h>
using namespace std;
void helix(string &strand1, string &strand2)
{
int nucleo;
int length;
if (strand1.length() >= strand2.length())
{
length = strand1.length();
}
else
{
length = strand2.length();
}
int add;
for (int add = 0; add <= length - 1; add++)
{
if (add > 7)
{
nucleo = add % 8;
}
else
{
nucleo = add;
}
if (nucleo == 0)
{
cout << " " << strand1[add] << "---"<<strand2[add] << endl;
}
else if (nucleo == 1)
{
cout << " " << strand1[add] << "------" << strand2[add] << endl;
}
else if (nucleo == 2)
{
cout << " " << strand1[add] << "------" << strand2[add] << endl;
}
else if (nucleo == 3)
{
cout << " " << strand1[add] << "---" << strand2[add] << endl;
cout << " *" << endl;
}
else if (nucleo == 4)
{
cout << " " << strand2[add]<<"---" << strand1[add] << endl;
}
else if (nucleo == 5)
{
cout << " " << strand2[add]<<"------" << strand1[add] << endl;
}
else if (nucleo == 6)
{
cout << " " << strand2[add]<<"------" << strand1[add] << endl;
}
else if (nucleo == 7)
{
cout << " " << strand2[add]<<"-----" << strand1[add] << endl;
cout << " *" << endl;
}
}
}
int main()
{
string strand1,strand2;
cout << "ENTER STRAND:" << endl;
cin >> strand1;
cout << "ENTER STRAND:" << endl;
cin >> strand2;
helix(strand1,strand2);
_getch();
return 0;
}
I was hoping I could still show the longer strand even if the other side of the strand is empty(want to put *) like this :imgur.com/t7riVrS
I think you inverted the legnth test, it should be:
//if (strand1.length() >= strand2.length())
if (strand1.length() < strand2.length())
{
length = strand1.length();
}
else
{
length = strand2.length();
}
Edit:
If you want it fill one the string with '*', replace the code above with:
while (strand1.length() < strand2.length())
{
strand1 += "*";
}
while (strand1.length() > strand2.length())
{
strand2 += "*";
}
cI want to select some text with my cursor using the Mark Function from Console, but my code doesn't work ...
CONSOLE_SELECTION_INFO c;
if(GetConsoleSelectionInfo(&c))
{
while((c.dwFlags & CONSOLE_MOUSE_DOWN) == 0) { if(c.dwFlags) cout << c.dwFlags; }
cout << "SelectionAnchor: " << c.dwSelectionAnchor.X << " " << c.dwSelectionAnchor.Y;
cout << "RectangleSelection: " << c.srSelection.Top << " " << c.srSelection.Left << c.srSelection.Bottom << c.srSelection.Right;
}
else cout << "\n\nError: " << GetLastError();
Whatever I'm selecting or I'm doing, always c.dwFlags will be 0 ...
I'm trying to initialize a file with 100 empty records with the code below:
void initializeInventory() {
std::ofstream out("hardware.dat", std::ios::binary);
Hardware h;
for (int i = 0; i < 100; ++i) {
h.ID = i;
h.name = "try"; // std::string();
h.quantity = 0;
h.price = 0;
h.notes = "try2"; //std::string();
out.write(reinterpret_cast<const char*>(&h), sizeof(Hardware));
}
out.close();
}
But when I try to print them out, it always print only 25 elements or crashes.
This is the function to print out elements:
void readInventory() {
std::ifstream in("hardware.dat", std::ios::in);
std::cout << std::setiosflags(std::ios::left) << std::setw(4) << "ID"
<< std::setw(16) << "Name"
<< std::setw(11) << "Quantity"
<< std::setw(10) << std::resetiosflags(std::ios::left)
<< "Price"
<< std::setw(50) << "Notes" << '\n';
Hardware h;
while (!in.eof()) {
in.read(reinterpret_cast<char*>(&h), sizeof(Hardware));
//if (!in.eof())
printOut(std::cout, h);
}
in.close();
}
void printOut(std::ostream &output, const Hardware& h) {
output << std::setiosflags(std::ios::left) << std::setw(4) << h.ID
<< std::setw(16) << h.name
<< std::setw(11) << h.quantity
<< std::setw(10) << std::setprecision(2)
<< std::resetiosflags(std::ios::left)
<< std::setiosflags(std::ios::fixed | std::ios::showpoint )
<< h.price
<< std::setw(50) << h.notes << '\n';
}
I also noted that if I increase the number of cycles in the for (I tried putting 400 instead of 100) the file hardware.dat seems to grow, so I thought that should be a problem in the print function. Any idea? Is there something I'm missing?
Thanks in advance.
It would be the best to overload the operator <<
friend ostream& operator<<(ostream& out, const Hardware& h) // output
{
out << "(" << h.id() << ", " << h.whatever() << ")";
return out;
}
and read the file line by line to the Hardware object.
By the way, overloading the input operator >> is also possible.