I have a problem.
I have a struct, "Figure", and one of its members, "vertices" is a pointer to another struct, "Point".
I have created an array of pointers to the data type struct "Figure"
Now I need to create an array of pointers to the data struct "Point", which is a member of the struct "Figure".
Can anyone please help me?
This is what I have so far.
#include <cstdlib>
#include <cstdio>
#include <cstring>
using namespace std;
struct Point // Point Structure
{
float x;
float y;
};
int main()
{
char LINE[300];
int numOfFigures;
char SHAPE;
char * LABEL = new char[50];
FILE * pFile;
pFile = fopen ("a3q2tmp.txt", "w+"); //opening file to store user input
if (pFile != NULL)
{
printf("How many figures: "); //determining how many Figures to work with
scanf("%i%*c", &numOfFigures);
Figure * FigPtr = new Figure [numOfFigures];
for (int i = 1; i < numOfFigures + 1; i++)
{
printf("Figure %i: ", i);
fgets (LINE, 300, stdin);
fputs (LINE, pFile);
rewind (pFile);
fscanf(pFile, "%c", &SHAPE);
FigPtr[i].shape = SHAPE;
//printf("%c", FigPtr[i].shape);
fscanf(pFile, "%s", LABEL);
FigPtr[i].label = LABEL;
//printf("%s", FigPtr[i].label);
if (FigPtr[i].shape == "T")
{
//This is where i need to create an array of pointers
//to the data type struct Point. And this array has to be
//stored in the member vertices of struct Figure
}
:-( Use the power of C++ so you don't have to care about it.
Plus, you are missing a data member in Figure to hold the number of vertices in the array.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
struct Figure
{
char shape;
Point *vertices;
unsignedint t_vertices; //The total of vertices in the array. You are missing this information.
char *label;
//This is C++ in all of its glory.
Figure() : shape('\0'), vertices(0), t_vertices(0), label(0)
{ }
//This is the destructor. Will delete the array of vertices, if present.
~Figure()
{
if (vertices) delete[] vertices;
}
}
Very simple, and will relieve you from thinking "Am I leaking memory?". No more memory leaks. Whenever you destroy a Figure (or one goes out of scope), you'll also destroy the associated vertices array. And that is C++. :-)
Then the C way of doing it would be to loop through the array of figures and call delete[] FigPtr(i).vertices; before destroying the said array of figures. Hardly impressive, prone to errors, and on more complex projects, just a pain to maintain.
The Point struct doesn't leak memory because its members are not dynamically allocated. In other words, you do not need to provide clean up for an instance of the Point struct, and therefore you don't need to write a constructor or destructor for them for this particular purpose.
By the way, the default constructor and destructor I wrote are the start. The absolute minimum should also cover the copy constructor and the assignment operator.
It should be FigPtr[i].vertices. The -> applies to pointers only. Your array is an array of Figures, not an array of pointers to Figures. Use the period.
+1 to what webJose is preaching, although you still have to worry about memory problems with his setup.
If you want to get a solid handle on memory allocation and be SURE that you're not leaking or corrupting memory, you have to encapsulate.
The idea is simple. If Figure contains dynamically allocated memory... then Figure should be responsible for allocating AND freeing the memory. What's more, Figure should be impossible to misuse and produce a memory leak. IE: you want to make it idiotproof so that you don't shoot yourself in the foot later. This is why you would make some members private -- so that you can't mess with them in a way which would cause leaks/crashes/etc.
There are a dozen ways the above Figure class could leak memory, delete the wrong thing, or delete the same buffer twice. Therefore it's not an ideal solution.
Of course... the easy solution here is to just use STL container classes:
if (FigPtr[i].shape == 'T')
{
FigPtr[i].vertices = new Point[3];
for (int j = 0; j < 3; j++)
{
fscanf(pFile, "%f", &xVert); //There is a problem here
FigPtr[i].vertices[j].x = xVert;
fscanf(pFile, "%f", &yVert); //There is a problem here
FigPtr[i].vertices[j].y = yVert;
printf("%f\n", FigPtr[i].vertices[j].x);
printf("%f\n", FigPtr[i].vertices[j].y);
}
}
}
With the 2 line above that i marked there is an issue. when my file contains the floating point numbers separated by spaces it works
fine but when the numbers are separated by commas it give me weird numbers, not the numbers i expected.
example: when reading in 0.0 0.1 0.2 0.3 0.4 0.5 it works as expected
but when reading in 0.0,0.1 0.2,0.3 0.4,0.5 it reads the first float correctly then I get really large numbers instead of the ones I expect
After that, get into STL. To be honest, I am not much of an STL guy, and that hurts me more often than not. Still, you should read about STL streams and do your file IO with them. They are easier to work with.
P. S.: When posting code, please use the CODE tags.
I know this looks like C but the course requires i program like this, using <cstdlib> and <cstdio> that is why i have been coding like
that. For what ever reason when I use fscanf, if the numbers are only seperated by a comma it doest read the float at store it in xVert or yVert. Why is that?
Well, the comma is the thousands separator. This may be interfering with the read operation. Are you required to have that file format? I would have created a binary file and just read entire structs at a time. Well, that's a simplification. I would have created a binary file with a header telling me the offset and amount of Figure structs in the file, and telling me the offset of the vertices in the file. I would have then looped through the file creating the Figures, and then loading the vertices. But that's just me. :-)
Going back to your problem, can't you just use the text file with spaces? Like I said, I don't use fscanf(), and haven't used it for soooo long. I am not of big help there. And for that matter, I haven't read files with STL streams for almost the same time. I am a Windows guy and always use the Windows API.