0

I'm getting this error when I compile, but I'm not sure how to fix it. I see that it has something to do with trying to use ofstream outFile; to write to a file. I've diddled with it, but I'm not sure what the problem is.

1>Rectangle.obj : error LNK2001: unresolved external symbol "class std::basic_ofstream<char,struct std::char_traits<char> > outFile" (?outFile@@3V?$basic_ofstream@DU?$char_traits@D@std@@@std@@A)
1>E:\Hw11_overload_Hw8\Debug\Rectangle.exe : fatal error LNK1120: 1 unresolved externals

This is my header file.

#ifndef Rectangle_h
#define Rectangle_h

#include <iostream>  
#include <fstream>
#include <sstream>

using namespace std;

class Rectangle
{

friend istream &operator>> (istream &input, Rectangle &grid);
friend ostream &operator<< (ostream &output, Rectangle grid);

private:
int i, j, h, x1, x2, y1, y2, perimeter, area, width, height;
char inner, outer;
string name;

public:
Rectangle();

void printGrid();

void setX1(int x11);
int getX1();
void setX2(int x21);
int getX2();
void setY1(int y11);
int getY1();
void setY2(int y21);
int getY2();

void setInner(char inner1);
char getInner();
void setOuter(char outer1);
char getOuter();

void findPerimeter();
void findArea();
void findWidth();
void findHeight();

void setName(string name1);
string getName();

int Menu();

};

#endif

And here is my source file.

#include "Rectangle.h"

extern ofstream outFile;

Rectangle::Rectangle()
{
x1 = 0;
x2 = 1;
y1 = 0;
y2 = 1;
}

void Rectangle::setX1(int x11)
{
x1 = x11;
}

int Rectangle::getX1()
{
return x1;
}

void Rectangle::setX2(int x21)
{
x2 = x21;
}

int Rectangle::getX2()
{
return x2;
}

void Rectangle::setY1(int y11)
{
y1 = y11;
}

int Rectangle::getY1()
{
return y1;
}

void Rectangle::setY2(int y21)
{
y2 = y21;
}

int Rectangle::getY2()
{
return y2;
}

void Rectangle::findPerimeter()
{
perimeter = ((x2 - x1) + (y2 - y1)) * 2;
cout << "The perimeter of the rectangle is: " << perimeter << endl;
}

void Rectangle::findArea()
{
area = (x2 - x1) * (y2 - y1);
cout << "The area of the rectangle is: " << area << endl;
}

void Rectangle::findWidth()
{
width = x2 - x1;
cout << "The width of the rectangle is: " << width << endl;
}

void Rectangle::findHeight()
{
height = y2 - y1;
cout << "The height of the rectangle is: " << height << endl;
}

void Rectangle::setInner(char inner1)
{
    inner = inner1;
}
char Rectangle::getInner()
{
return inner;
}

void Rectangle::setOuter(char outer1)
{
outer = outer1;
}
char Rectangle::getOuter()
{
return outer;
}

void Rectangle::setName(string name1)
{
name = name1;
}

string Rectangle::getName()
{
return name;
}

void Rectangle::printGrid()
{
int numrows = 25;
int numcols = 25;
int current_row = numrows; // starting row number
int current_col = 1; // starting col number
char output = '.';

for(i = 0; i < numrows; i++)        // prints 25 rows of 25 dots 
{   

    cout << current_row << '\t';    // Print out current row number
    outFile << current_row << '\t';

    //This is out loop for each ROW
    //Print out dots in each row OR stuff for the rectangle
    for(j = 1; j <= numcols; j++) {

        output = '.'; // Initialize output with our default value of "."


        if ((current_col >= x1) && (current_col <= x2) && (current_row >=    y1) && (current_row <= y2)) {
            output = outer;
        }

        if ((current_col > x1) && (current_col < x2) && (current_row > y1) && (current_row < y2)) {
            output = inner;
        }

        cout << output << "  "; // output our "output" value and a space            
        outFile << output << "  ";
        current_col++;  //Increment current column, because this is the end of this column loop iteration

    } // Close column loop

    cout << endl;       //...and a new line
    outFile << endl;

    current_col = 1;    // reset column count for next iteration
    current_row--;      // decrement current row number

} // Close Row loop


//output column labels across bottom line
cout << '\t';
outFile << '\t';

// put 1 -> 25 across the bottom
for (i = 1; i <= 25; i++)
{
    if(i < 10)
    {
        cout << i << "  ";
        outFile << i << "  ";
    }

    if(i > 9)
    {
        cout << i << " ";
        outFile << i << " ";
    }
}

// Spit out a couple of blank lines
cout << endl << endl;
outFile << endl << endl;
}

int Rectangle::Menu()
{
ifstream inFile;

int choice;

cout << "1. Enter information about a rectangle. " << endl;
cout << "2. Search for a rectangle. " << endl;
cout << "3. Print the perimeter and the area of the rectangle. " << endl;
cout << "4. Print the width and height of the rectangle. " << endl;
cout << "5. Draw a particular rectangle. " << endl;
cout << "6. Quit. " << endl;
cout << "Enter your choice. " << endl;
inFile >> choice;
cout << endl << endl;

return choice;
}

istream &operator>> (istream &input, Rectangle &grid)
{
ifstream inFile;
ofstream outFile;

Rectangle rect[10];
int x11, x21, y11, y21, choice, numRectangles = 0, i = 0;
char inner1, outer1;
string name1;

inFile.open ("rectangle.in");
outFile.open ("rectangle.out");

if (!inFile)
{
    cout << "ERROR:  inFile does not exist. " << endl;
    system("pause");
}

if (!outFile)
{
    cout << "ERROR:  outFile does not exist. " << endl;
    system("pause");
}

choice = rect[i].Menu();

while(choice >= 1 && choice <= 6)
{
    if(choice == 1)
    {   do
        {
            cout << "Enter x1, x2, y1, and y2 such that x1 < x2 and y1 <  y2: " << endl;
            inFile >> x11;
            inFile >> x21;
            inFile >> y11;
            inFile >> y21;
            cout << "Enter a character for the interior of the   rectangle. \n";
            inFile >> inner1;
            cout << "Enter a character for the exterior of the rectangle. \n";
            inFile >> outer1;
            cout << "Enter a name for the rectangle. \n";
            inFile >> name1;

            rect[numRectangles].setX1(x11);
            rect[numRectangles].setX2(x21);
            rect[numRectangles].setY1(y11);
            rect[numRectangles].setY2(y21);
            rect[numRectangles].setInner(inner1);
            rect[numRectangles].setOuter(outer1);
            rect[numRectangles].setName(name1);

            numRectangles++;
        }
        while(x11 >= x21 || y11 >= y21);
            cout << endl << "Rectangle accepted. \n" << endl;
    }

if (choice == 2)
    {
        cout << "To search for a rectangle, enter the name of the rectangle.  " << endl;
        cin >> name1;

        for(i = 0; i < numRectangles; i++)
            {
                if(name1 == rect[i].getName())
                {
                    rect[i].findPerimeter();
                    rect[i].findArea();
                    rect[i].findWidth();
                    rect[i].findHeight();
                    rect[i].printGrid();
                    system("pause");
                }
            }
        if(name1 != rect[i].getName())
            {
                cout << "ERROR! Rectangle doesn't exist!" << endl <<  endl;
                system("pause");
            }
    }

    if(choice == 3)
    {
        for(i = 0; i < numRectangles; i++)
        {
            rect[i].findPerimeter();
            cout << endl;
            rect[i].findArea();
            cout << endl;
        }
    }

    if(choice == 4)
    {
        for(i = 0; i < numRectangles; i++)
            {
                rect[i].findWidth();
                cout << endl;
                rect[i].findHeight();
                cout << endl;
            }
    }   

    if(choice == 5)
    {
        for(i = 0; i < numRectangles; i++)
        {
            rect[i].printGrid();
            cout << endl;
        }
    }

    if(choice == 6)
        {
            cout << "Bye bye!" << endl;
            system("pause");
        }

    choice = rect[i].Menu();
    return input;

}   // End of while loop

inFile.close();
outFile.close();

}

ostream &operator<< (ostream &output, Rectangle grid)
{
return output;
}

And here is my main function

#include "Rectangle.h"

int main()

Rectangle rect[10];

int numRectangles;

for(int i = 0; i < numRectangles; i++)
{
    cin >> rect[i];
    cout << rect[i];
}

}

1 Answers1

0

Problems:

You have declared that outFile will have external linkage. std::ofstream has no default constructor.

std::ofstream has a non-default constructor and takes two parameters.. The first is the location of the file and the second (which is default btw) is how you plan to open/write it.

Thus you can fix this error by replacing extern ofstream outFile; with:

ofstream outFile("output.txt"); within Rectangle.cpp

There is no need to declare it as extern within the .cpp file as far as I am aware.


Next, istream& operator>> (istream& input, Rectangle& grid) is returning NOTHING..

It should be returning input before the function finishes.


Finally, you are missing a curly bracket after main's () brackets.

You main.cpp should look like:

#include "Rectangle.h"

int main()
{
    Rectangle rect[10];

    int numRectangles;

    for(int i = 0; i < numRectangles; i++)
    {
        cin >> rect[i];
        cout << rect[i];
    }
}

Would it really kill you to follow convention and format your code?

If done correctly, your code would look like:

Rectangle.h:

#ifndef Rectangle_h
#define Rectangle_h

#include <iostream>
#include <fstream>
#include <sstream>

using namespace std;

class Rectangle
{
    private:
        friend istream& operator>> (istream& input, Rectangle& grid);
        friend ostream& operator<< (ostream& output, Rectangle grid);

        int i, j, h, x1, x2, y1, y2, perimeter, area, width, height;
        char inner, outer;
        string name;

    public:
        Rectangle();

        void printGrid();

        void setX1(int x11);
        int getX1();
        void setX2(int x21);
        int getX2();
        void setY1(int y11);
        int getY1();
        void setY2(int y21);
        int getY2();

        void setInner(char inner1);
        char getInner();
        void setOuter(char outer1);
        char getOuter();

        void findPerimeter();
        void findArea();
        void findWidth();
        void findHeight();

        void setName(string name1);
        string getName();

        int Menu();

};

#endif

Rectangle.cpp:

#include "Rectangle.h"

ofstream outFile("output.txt");

Rectangle::Rectangle()
{
    x1 = 0;
    x2 = 1;
    y1 = 0;
    y2 = 1;
}

void Rectangle::setX1(int x11)
{
    x1 = x11;
}

int Rectangle::getX1()
{
    return x1;
}

void Rectangle::setX2(int x21)
{
    x2 = x21;
}

int Rectangle::getX2()
{
    return x2;
}

void Rectangle::setY1(int y11)
{
    y1 = y11;
}

int Rectangle::getY1()
{
    return y1;
}

void Rectangle::setY2(int y21)
{
    y2 = y21;
}

int Rectangle::getY2()
{
    return y2;
}

void Rectangle::findPerimeter()
{
    perimeter = ((x2 - x1) + (y2 - y1)) * 2;
    cout << "The perimeter of the rectangle is: " << perimeter << endl;
}

void Rectangle::findArea()
{
    area = (x2 - x1) * (y2 - y1);
    cout << "The area of the rectangle is: " << area << endl;
}

void Rectangle::findWidth()
{
    width = x2 - x1;
    cout << "The width of the rectangle is: " << width << endl;
}

void Rectangle::findHeight()
{
    height = y2 - y1;
    cout << "The height of the rectangle is: " << height << endl;
}

void Rectangle::setInner(char inner1)
{
    inner = inner1;
}
char Rectangle::getInner()
{
    return inner;
}

void Rectangle::setOuter(char outer1)
{
    outer = outer1;
}
char Rectangle::getOuter()
{
    return outer;
}

void Rectangle::setName(string name1)
{
    name = name1;
}

string Rectangle::getName()
{
    return name;
}

void Rectangle::printGrid()
{
    int numrows = 25;
    int numcols = 25;
    int current_row = numrows; // starting row number
    int current_col = 1; // starting col number
    char output = '.';

    for(i = 0; i < numrows; i++)        // prints 25 rows of 25 dots
    {

        cout << current_row << '\t';    // Print out current row number
        outFile << current_row << '\t';

        //This is out loop for each ROW
        //Print out dots in each row OR stuff for the rectangle
        for(j = 1; j <= numcols; j++)
        {

            output = '.'; // Initialize output with our default value of "."


            if ((current_col >= x1) && (current_col <= x2) && (current_row >=    y1) && (current_row <= y2))
            {
                output = outer;
            }

            if ((current_col > x1) && (current_col < x2) && (current_row > y1) && (current_row < y2))
            {
                output = inner;
            }

            cout << output << "  "; // output our "output" value and a space
            outFile << output << "  ";
            current_col++;  //Increment current column, because this is the end of this column loop iteration

        } // Close column loop

        cout << endl;       //...and a new line
        outFile << endl;

        current_col = 1;    // reset column count for next iteration
        current_row--;      // decrement current row number

    } // Close Row loop


//output column labels across bottom line
    cout << '\t';
    outFile << '\t';

// put 1 -> 25 across the bottom
    for (i = 1; i <= 25; i++)
    {
        if(i < 10)
        {
            cout << i << "  ";
            outFile << i << "  ";
        }

        if(i > 9)
        {
            cout << i << " ";
            outFile << i << " ";
        }
    }

// Spit out a couple of blank lines
    cout << endl << endl;
    outFile << endl << endl;
}

int Rectangle::Menu()
{
    ifstream inFile;

    int choice;

    cout << "1. Enter information about a rectangle. " << endl;
    cout << "2. Search for a rectangle. " << endl;
    cout << "3. Print the perimeter and the area of the rectangle. " << endl;
    cout << "4. Print the width and height of the rectangle. " << endl;
    cout << "5. Draw a particular rectangle. " << endl;
    cout << "6. Quit. " << endl;
    cout << "Enter your choice. " << endl;
    inFile >> choice;
    cout << endl << endl;

    return choice;
}

istream& operator>> (istream& input, Rectangle& grid)
{
    ifstream inFile;
    ofstream outFile;

    Rectangle rect[10];
    int x11, x21, y11, y21, choice, numRectangles = 0, i = 0;
    char inner1, outer1;
    string name1;

    inFile.open ("rectangle.in");
    outFile.open ("rectangle.out");

    if (!inFile)
    {
        cout << "ERROR:  inFile does not exist. " << endl;
        system("pause");
    }

    if (!outFile)
    {
        cout << "ERROR:  outFile does not exist. " << endl;
        system("pause");
    }

    choice = rect[i].Menu();

    while(choice >= 1 && choice <= 6)
    {
        if(choice == 1)
        {
            do
            {
                cout << "Enter x1, x2, y1, and y2 such that x1 < x2 and y1 <  y2: " << endl;
                inFile >> x11;
                inFile >> x21;
                inFile >> y11;
                inFile >> y21;
                cout << "Enter a character for the interior of the   rectangle. \n";
                inFile >> inner1;
                cout << "Enter a character for the exterior of the rectangle. \n";
                inFile >> outer1;
                cout << "Enter a name for the rectangle. \n";
                inFile >> name1;

                rect[numRectangles].setX1(x11);
                rect[numRectangles].setX2(x21);
                rect[numRectangles].setY1(y11);
                rect[numRectangles].setY2(y21);
                rect[numRectangles].setInner(inner1);
                rect[numRectangles].setOuter(outer1);
                rect[numRectangles].setName(name1);

                numRectangles++;
            }
            while(x11 >= x21 || y11 >= y21);
            cout << endl << "Rectangle accepted. \n" << endl;
        }

        if (choice == 2)
        {
            cout << "To search for a rectangle, enter the name of the rectangle.  " << endl;
            cin >> name1;

            for(i = 0; i < numRectangles; i++)
            {
                if(name1 == rect[i].getName())
                {
                    rect[i].findPerimeter();
                    rect[i].findArea();
                    rect[i].findWidth();
                    rect[i].findHeight();
                    rect[i].printGrid();
                    system("pause");
                }
            }
            if(name1 != rect[i].getName())
            {
                cout << "ERROR! Rectangle doesn't exist!" << endl <<  endl;
                system("pause");
            }
        }

        if(choice == 3)
        {
            for(i = 0; i < numRectangles; i++)
            {
                rect[i].findPerimeter();
                cout << endl;
                rect[i].findArea();
                cout << endl;
            }
        }

        if(choice == 4)
        {
            for(i = 0; i < numRectangles; i++)
            {
                rect[i].findWidth();
                cout << endl;
                rect[i].findHeight();
                cout << endl;
            }
        }

        if(choice == 5)
        {
            for(i = 0; i < numRectangles; i++)
            {
                rect[i].printGrid();
                cout << endl;
            }
        }

        if(choice == 6)
        {
            cout << "Bye bye!" << endl;
            system("pause");
        }

        choice = rect[i].Menu();
        return input;

    }   // End of while loop

    inFile.close();
    outFile.close();
    return input;
}

ostream& operator<< (ostream& output, Rectangle grid)
{
    return output;
}

main.cpp:

#include "Rectangle.h"

int main()
{
    Rectangle rect[10];

    int numRectangles;

    for(int i = 0; i < numRectangles; i++)
    {
        cin >> rect[i];
        cout << rect[i];
    }
}

I did not check anything else other than getting it to compile. That means I am not sure if you have any bugs preventing it from running correctly. I also would advice you to avoid using using namespace std; in header files.

Brandon
  • 22,723
  • 11
  • 93
  • 186
  • I'm new to this site and have been wondering how to format it the way I've been seeing it. – user3254558 Apr 11 '14 at 19:19
  • Welcome to the stackoverflow. The website itself has no formatter (that I know of) but if you use an IDE, it should have the option to format. For example, in Code-Blocks IDE, you can right click a file to format it or right click the project to format it. If using Netbeans, right click format is also there. Visual Studio has it in one of its many menus (maybe edit or view menu). – Brandon Apr 11 '14 at 19:23