How to fix these 4 errors?

This program is supposed to read in a txt file whose first line states the number of rectangles and the lines after state the height and width. Any help you could give me in explaining these errors/how to fix them is greatly appreciated, thank you. :) The errors I'm having trouble with are "invalid operands to binary expression" and "type 'rectangle' does not provide a subscript operator". All the errors are in main.cpp. The exact wording is at this line in main.cpp "in >> r;" it says "invalid operands to binary expression ('if stream' (aka 'basic_ifstream<char>') and 'Rectangle'). The line "cout << r[0] << " x " << r[1] << endl;" says "type 'Rectangle' does not provide a subscript operator". Line "cout << r;" says "invalid operands to binary expression ('stream' (aka 'basic_stream<char>') and 'Rectangle')". And line "Rectangle r1(4, 5), r2(10, 2); if ( r1 == r2 ) {" says "invalid operands to binary expression ('Rectangle' and 'Rectangle')"

heres
rectangle.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#ifndef homework_rectangle_h
#define homework_rectangle_h
class Rectangle {
public:
    Rectangle(double w=1, double h=1);
    
    double getWidth();
    void setWidth(double w);
    
    double getHeight();
    void setHeight(double h);
    
    double getArea();
    double getPerimeter();
    
private:
    double height;
    double width;
};

#endif


rectangle.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include "rectangle.h"
#include <iostream>
using namespace std;

Rectangle::Rectangle(double w, double h):width(w),height(h) {}

double Rectangle::getWidth() { return width; }

void Rectangle::setWidth(double w) {width = w; }

double Rectangle::getHeight() { return height; }

void Rectangle::setHeight(double h) { height = h; }

double Rectangle::getArea() { return width*height; }

double Rectangle::getPerimeter() { return 2*(width+height); }


and main.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include "rectangle.h"
#include <iostream>
#include <fstream> 
#include <string> 

using namespace std;

int main() {
ifstream in("input.txt"); int numRectangles;
in >> numRectangles;
for ( int i = 0; i < numRectangles; i++ ) { Rectangle r;
    in >> r;
    cout << r[0] << " x " << r[1] << endl;
    cout << r;
    }
    Rectangle r1(4, 5), r2(10, 2); if ( r1 == r2 ) {
        cout << "Both rectangles have the same area!" << endl; }
}

There are a number of errors with just this main.cpp namely:
line 11, Rectangle r is an error because the Rectangle class does not have a default constructor

line 12, in >> r is an error because you have not overloaded the >> operator for Rectangle

line 13, the error message you got is saying that Rectangle class did not overload the subscript operator, so you cannot do r[0] or r[1]

line 14, cout << r; this is an error because you have not overloaded the << operator for Rectangle

line 16, if ( r1 == r2 ), another error because you did not overload the == operator for Rectangle

Easy fix for line 11, create a default constructor in the Rectangle class
Easy fix for line 13/14, use Rectangle::getWidth, Rectangle::getHeight
Easy fix for line 12, in the Rectangle.h file:
1
2
3
4
friend istream& operator >> (istream &iss, Rectangle& r) {
    iss >> r.height >> r.width;
    return iss;
}


For line 16, use the example I've just shown above to overload the == operator (return type is bool), or simply just use Rectangle::getWidth, Rectangle::getHeight
Last edited on
thanks Smac89:i fixed some of the errors but i don't know what you mean by use Rectangle::getWidth, Rectangle::getHeight aren't I using them already?
@Smac89: Your line 12 fix can violate ODR.
smac89 wrote:
line 11, Rectangle r is an error because the Rectangle class does not have a default constructor

The constructor at liine 5 in the header serves as a default constructor since both arguments have default values.


@S G H How does it violate ODR?
@AbstractionAnon Fixed that
Make two .cpp files and include that header in both cpp files.
Linker error incoming.
You mean like what OP has already?
Yes, exactly. If TC tries your fix, you will have a problem as operator<< will be defined twice (once in rectangle.cpp, and again in main.cpp).
OP is having compiler errors.
I am talking about linker errors.
Compiler errors pop up right away.
Linker errors pop up when there's nomore compiler errors.
I'm really confused now. how do i go about fixing the problems with the code if Smac89's way doesn't work?
Last edited on
Simply put only the declaration of the >> operator in the header file.

12
13
// rectangle.h
friend istream& operator >> (istream &iss, Rectangle& r);


Then put the implementation in rectangle.cpp
1
2
3
4
5
//  rectangle.cpp
istream& operator >> (istream &iss, Rectangle& r) 
{  iss >> r.height >> r.width;
    return iss;
}


The problem was that the implementation was in the header file and by including the header file in two .cpp files, you would have had two implementations for the same function.
thanks :) i fixed that but still have 2 errors. in main.cpp cout << r[0] << " x " << r[1] << endl; says type 'Rectangle' does not provide a subscript operator and Rectangle r1(4, 5), r2(10, 2); if ( r1 == r2 ) { says invalid operands to binary expression ('Rectable' and 'Rectangle')
main.cpp
Line 11: Rectange r is not an array. Therefore at line 13, you can;t reference r[0] or r[1].

What I presume you want here is:
 
cout << r.get_width() << " x " << r.get_height() << endl;


main.cpp
Line 16: You're trying to compare two Rectangle objects, but your class has no overload for operator ==.
1
2
  // Declaration for equality operator
  bool operator == (const Rectangle & r) const;


I'll let you write the implementation.
ok thanks. and i also wanted it to print the rectangles out in stars, for example
3x3
***
***
***

would it be something like this loop?
cin>>x;
for(int i= 0;i<=v;i++)
{
for(int j=0;j<=x;j++)
{
cout<<"*";

}
cout<<endl;
}
return 0;
}
and how would i connect it in a simple way?
Your loops should be <, not <= since the loop count starts at 0.

how would i connect it in a simple way?

I don't know what you mean by "connect it".
Do you mean to draw it as an outlne? i.e. only the perimeter?

No I meant where to insert it in my code this is what i wrote but now theres an error that h is undefined. ill show you. the error is in main where i called PrintChar

rectangle.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#include <iostream>
#ifndef homework_rectangle_h
#define homework_rectangle_h
class Rectangle {
public:
    Rectangle(double w=1, double h=1);
   
    
    bool operator == (const Rectangle & r) const;
    
    double getWidth();
    void setWidth(double w);
    
    double getHeight();
    void setHeight(double h);
    
    double getArea();
    double getPerimeter();
    void PrintChar(int w = 1, int h = 1, char symbol = '*');
    
    friend std::istream& operator >> (std::istream &iss, Rectangle& r);

    
private:
    double height;
    double width;
};


#endif 


main.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#include "rectangle.h"
#include <iostream>
#include <fstream>
#include <string>

using namespace std;

istream& operator >> (istream &iss, Rectangle& r)
{  iss >> r.height >> r.width;
    return iss;
}

int main() {
    cout << r.get_width() << " x " << r.get_height() << endl;
    ifstream in("input.txt"); int numRectangles;
    in >> numRectangles;
    for ( int i = 0; i < numRectangles; i++ ) { Rectangle r;
        in >> r;
        cout << r[0] << " x " << r[1] << endl;
        cout << &r;
    }
    PrintChar(h, w, symbol);
    
    Rectangle r1(4, 5), r2(10, 2); if ( r1 == r2 ) {
        cout << "Both rectangles have the same area!" << endl; }
}


rectangle.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#include "rectangle.h"
#include <iostream>
using namespace std;

Rectangle::Rectangle(double w, double h):width(w),height(h) {}

double Rectangle::getWidth() { return width; }

void Rectangle::setWidth(double w) {width = w; }

double Rectangle::getHeight() { return height; }

void Rectangle::setHeight(double h) { height = h; }

double Rectangle::getArea() { return width*height; }

double Rectangle::getPerimeter() { return 2*(width+height); }

void Rectangle::PrintChar(int h, int w, char symbol) {
    for (int y = 1; y <= w; y++) {
        for (int x = 1; x <= h; x++) {
            cout << symbol;
        }
        cout << endl;
    }
}

Last edited on
Several problems still exist in main:
Line 14: r is not defined. Calls to get_width() and get_height() need an instance of a Rectangle.

Line 19: You're trying to output an array of rectangles. You haven't overloaded the >> operator in your Rectangle class. From the code, though it looks like you're trying to output the dimensions of a rectangle. Using the subscript operator is not the way do do that. I showed you how to do this previously. See my comment regarding line 11 above. Did you mean to put line 14 here?

Line 22: Yeah, h and w are not defined because you never declared them. PrintChar is a member of the Rectangle class, so you have to refer to a specific instance of a Rectangle to call PrintChar(). What rectangle are you trying to print? Also, symbol is not defined within main.

BTW, the PrintChar function does not need to be passed h and w. height and width are member variables of the Rectangle class. You should use those.

The following would work if placed after line 25 (assuming you remove h and w as arguments):
 
  r1.PrintChar ('*');








wow all my errors are gone. now i just have to figure out overloading the operator ==. thank you very much you're a lifesaver!!
Topic archived. No new replies allowed.