For my project, we're supposed to read data from a text file (circlemath.txt) and the program should output data for the circle to a text file (circoutput.txt). The input file contains data specific for class Circle (x-coordinate, y-coordinate, radius, ascii character), and each line has the form (Circle1 data, operator symbol, Circle2 data). We're supposed to overload the +, - , << , and >> operators to do specific tasks. The problem I'm having is reading in the file. We're supposed to read to eof, and when I try that, I get one extra line of data that is complete garbage. This garbage line causes my program to crash. I was wondering if anyone could tell me where the problem is. I've tried looking and I can't seem to find it. Here's all 3 of my source files as well as the input file.

circlemath.txt
0 0 2 $ + 0 0 1 *
0 0 2 * - 0 0 1 *
10 10 10 o - 5 5 5 ^
-5 15 5 # + 10 -5 10 &
20 20 20 . + 10 10 10 y

circle.h

#ifndef CIRCLE_H
#include <iostream>
using namespace std;

class Circle
{
   public:
      Circle();			// Constructor
      void setCoordinates(int x, int y);	// Mutator functions
      void setRadius(int r);
      void setASCIICharacter(char ch);
	  void setOp(char o);
      float computeArea();
      float computePerimeter();
      void displayCircleAttributes();
      void drawCircle();
      int getXCoord() const;		// Accessor functions
      int getYCoord() const;
      int getRadius() const;
      char getASCIICharacter() const;
	  char getOp() const;

	  Circle operator +(Circle circle);		// Overloaded operators
	  Circle operator -(Circle circle);
   private:
      int xCoord;			// Data members
      int yCoord;
      int radius;
      char asciiCharacter;
	  char op;
	 
	  friend istream& operator >>(istream &is, Circle &circle);		// Friend functions
	  friend ostream& operator <<(ostream &os, Circle &circle);	 
};		
#define CIRCLE_H
#endif

circle.cpp

#include<iostream>
#include<iomanip>
#include <cmath>
#include"circle.h"
using namespace std;

const float PI = 3.1416F;
const int PADDING = 3;

// This default constructor sets up the data members with default values. //
Circle::Circle()
{
   xCoord = yCoord = 0;
   radius = 1;
   asciiCharacter = ' ';
}
// Assign the x- and y- coords of the circle's center with parameterized values. //
void Circle::setCoordinates(int x, int y)
{
   xCoord = x;
   yCoord = y;
   return;
}
// Assign the radius of the circle the parameterized value. //
void Circle::setRadius(int r)
{
   if(r < 0)
	   radius = 1;
   else
	   radius = r;
   return;
}
// Assign the fill character of the circle the parameterized value. //
void Circle::setASCIICharacter(char ch)
{
   asciiCharacter = ch;
   return;
}
// Assign the Operator Character of the circle the parameterized value. //
void Circle::setOp(char o)
{
	op = o;
	return;
}
// Compute and return the area of the circle. //
float Circle::computeArea()
{
   return PI * radius * radius;
}

// Compute and return the perimeter of the circle. //
float Circle::computePerimeter()
{
   return 2 * PI * radius;
}
// Output the circle's data member values, as    //
// well as the area and perimeter of the Circle. //
void Circle::displayCircleAttributes()
{
   cout.setf(ios::fixed);
   cout << setprecision(4);
   cout << "Center's x-coordinate:   " << xCoord             << endl;
   cout << "Center's y-coordinate:   " << yCoord             << endl;
   cout << "Circle's radius:         " << radius             << endl;
   cout << "Circle's area:           " << computeArea()      << endl;
   cout << "Circle's perimeter:      " << computePerimeter() << endl;
   cout << "Circle's fill character: " << asciiCharacter     << endl;
}
// Output the Circle, using its ASCII character to draw it, //
// as well as vertical and horizontal symbols to draw the   //
// coordinate axes, and an 'X' at the center of the circle. //
void Circle::drawCircle()
{
   const int PADDING = 4;
   const float HEIGHT_WIDTH_RATIO = 1.5F;
   int lowerX = (xCoord-radius < -PADDING) ? (xCoord-radius-PADDING) : -PADDING;
   int upperX = (xCoord+radius >  PADDING) ? (xCoord+radius+PADDING) :  PADDING;
   int lowerY = (yCoord-radius < -PADDING) ? (yCoord-radius-PADDING) : -PADDING;
   int upperY = (yCoord+radius >  PADDING) ? (yCoord+radius+PADDING) :  PADDING;
   for (int y = upperY; y >= lowerY; y--)
   {
      for (int x = int(HEIGHT_WIDTH_RATIO*lowerX); x <= int(HEIGHT_WIDTH_RATIO*upperX); x++)
      {
         if ((x == xCoord) && (y == yCoord))
            cout << 'X';
         else if (pow(double(x-xCoord)/HEIGHT_WIDTH_RATIO,2)
                  + pow(double(y-yCoord),2) <= pow(double(radius),2))
            cout << asciiCharacter;
         else if ((x == 0) && (y == 0))
            cout << '+';
         else if (x == 0)
            cout << '|';
         else if (y == 0)
            cout << '-';
         else
            cout << ' ';
      }
      cout << endl;
   }
}
// Access and return the Circle's x-coordinate value. //
int Circle::getXCoord() const
{
   return xCoord;
}

// Access and return the Circle's y-coordinate value. //
int Circle::getYCoord() const
{
   return yCoord;
}

// Access and return the value of the Circle's radius. //
int Circle::getRadius() const
{
   return radius;
}

// Access and return the value of the Circle's ASCII fill character. //
char Circle::getASCIICharacter() const
{
   return asciiCharacter;
}
// Access and return the value of the Circle's Operator character. //
char Circle::getOp() const
{
	return op;
}
// Allows Circle's coordinates and Circle's radius to be added to another Circle. //
Circle Circle::operator +(Circle circle2)
{
	Circle circle3;

	circle3.xCoord = xCoord + circle2.xCoord;
	circle3.yCoord = yCoord + circle2.yCoord;
	circle3.radius = radius + circle2.radius;
	circle3.asciiCharacter = asciiCharacter;

	return circle3;
}
// Allows Circle's coordinates and Circle's radius to be subtracted from another Circle. //
Circle Circle::operator -(Circle circle2)
{
	Circle circle3;
	
	circle3.asciiCharacter = asciiCharacter;
	circle3.xCoord = xCoord - circle2.xCoord;
	circle3.yCoord = yCoord - circle2.yCoord;
	if(radius - circle2.radius < 1)
		circle3.radius = 1;
	else
		circle3.radius = radius - circle2.radius;
	

	return circle3;
}
// Allows data to be stored from a .txt file into a Circle object
istream& operator >>(istream &is, Circle &circle)
{
	int x,y, r;
	char sym;

	is >> x >> y >> r >> sym;
	circle.setCoordinates(x,y);
	circle.setRadius(r);
	circle.setASCIICharacter(sym);

	return is;
}
// Allows Circle data to be output to a destination file. 
ostream& operator <<(ostream &os, Circle &circle)
{
	static int counter(0), probNumber(0);
	counter ++;
	if(counter % 3 == 1)
	{
			probNumber++;
			os << "****************************************************" << endl;
			os << "*** Problem " << probNumber << endl;
			os << "****************************************************" << endl << endl;
	}
	if(counter % 3 == 2)
	{
		if(circle.op == '+')
			os << "Plus(+):" << endl;
		else if(circle.op == '-')
			os << "Minus(-):" << endl;
	}
	if(counter % 3 == 0)
		os << "Results in:" << endl;

	os.setf(ios::fixed);
	os << setprecision(4);
	os << "Center's x-coordinate:   " << circle.xCoord             << endl;
	os << "Center's y-coordinate:   " << circle.yCoord             << endl;
	os << "Circle's radius:         " << circle.radius             << endl;
	os << "Circle's area:           " << circle.computeArea()      << endl;
	os << "Circle's perimeter:      " << circle.computePerimeter() << endl;
	os << "Circle's fill character: " << circle.asciiCharacter     << endl;

	const int PADDING = 4;
	const float HEIGHT_WIDTH_RATIO = 1.5F;
	int lowerX = (circle.xCoord-circle.radius < -PADDING) ? (circle.xCoord-circle.radius-PADDING) : -PADDING;
	int upperX = (circle.xCoord+circle.radius >  PADDING) ? (circle.xCoord+circle.radius+PADDING) :  PADDING;
	int lowerY = (circle.yCoord-circle.radius < -PADDING) ? (circle.yCoord-circle.radius-PADDING) : -PADDING;
	int upperY = (circle.yCoord+circle.radius >  PADDING) ? (circle.yCoord+circle.radius+PADDING) :  PADDING;
	for (int y = upperY; y >= lowerY; y--)
	{
	  for (int x = int(HEIGHT_WIDTH_RATIO*lowerX); x <= int(HEIGHT_WIDTH_RATIO*upperX); x++)
	  {
		 if ((x == circle.xCoord) && (y == circle.yCoord))
			os << 'X';
		 else if (pow(double(x-circle.xCoord)/HEIGHT_WIDTH_RATIO,2)
				  + pow(double(y-circle.yCoord),2) <= pow(double(circle.radius),2))
			os << circle.asciiCharacter;
		 else if ((x == 0) && (y == 0))
			os << '+';
		 else if (x == 0)
			os << '|';
		 else if (y == 0)
			os << '-';
		 else
			os << ' ';
	  }
	  os << endl;
	}
	return os;
}

circleDriver.cpp

#include <iostream>
#include <fstream>
#include <assert.h>
#include "circle.h"
using namespace std;


void addCircles(Circle obj1, Circle obj2, Circle &circle3);
void subtractCircles(Circle obj1, Circle obj2, Circle &circle3);
void outputCompletionMessage();

int main()
{
	Circle circle1, circle2, circle3;
	char op;
	int counter(0);
	ifstream myfile;
	ofstream destination;
	myfile.open("circlemath.txt");
	destination.open("circlecoutput.txt");
	assert (!myfile.fail()); 
	while(!myfile.eof())
	{
			myfile >> circle1 >> op >> circle2;
			circle2.setOp(op);
			if(op == '+')
			{
				addCircles(circle1,circle2,circle3);
			}
			else
			{
				subtractCircles(circle1,circle2,circle3);
			}

			destination << circle1 << circle2 << circle3;
		
	}
		outputCompletionMessage();
		myfile.close();
	return 0;
	
}


void addCircles(Circle obj1, Circle obj2, Circle &circle3)
{
	circle3 = obj1 + obj2;
	return;
}

void subtractCircles(Circle obj1, Circle obj2, Circle &circle3)
{
	circle3 = obj1 - obj2;
	return;
}

void outputCompletionMessage()
{
	cout << "Processing Complete!\n\n\n";
	return;
}

Thou shalt not while(!myfile.eof()) .

Since Dave Sinkula is silent, let me take on this:

while(!myfile.eof())
        {
                        myfile >> circle1 >> op >> circle2;
                        do_something();
        }

Consider the last good iteration. It consumed all the bytes from myfile, but didn't try to read beyond its limits. The end of file hasn't been seen; eof condition has not been set. The loop enters the next round. Of course, the very first read now hits end of file, and whatever you attempt to read is garbage.

Ha, thanks for the tip. I guess in my rush to get the program done I forgot the golden rule. I understand what I did wrong. Thanks again.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.