# Thread: Check if the area and perimeter is the expected result

1. ## Check if the area and perimeter is the expected result

I have a program to calculate area and perimeter of a polygon. It reads each line of a text file, each line has some coordinates, and with that coordinates it calculates the area and the perimeter of the polygn.

To check if the output of the program corresponds to the correct area and perimeter I have 2 char arrays, each array corresponds to the correct result of each line of the file. The result array is to store the result values.

Code:
```char expected[] = "80.0036.00";  // area = 80.00 perimeter = 36.00
char expected1[] = "48.0032.00"; // area = 48.00 perimeter = 32.00
char result[] = "";              // its purpose is to store the result values```
The file coordinates.txt has two lines for now, the calculation result of the first line corresponds to the expected[] and the result of the other line corresponds to the expected1[]:
2 10 12 10 12 2 2 2
4 8 16 8 16 4 4 4

Im getting a problem that is altough the correct result "80.0036.00" is icual to the expected result "80.0036.00" the comparison result is always "Arrays are different". The same happens to the other lines. I also tried with sprintf but get same issue.

Code:
```while (fgets(line, sizeof (line), data)){
xycount = 0;
polygon_area = 0;
a = *(triangle*)malloc(sizeof (triangle));
memset(polygon_vertices, 0, sizeof (polygon_vertices));
line[strlen(line) - 1] = 0;
token = strtok(line, " ");
while (token != NULL){
xy = atof(token);
token = strtok(NULL, " ");
polygon_vertices[xycount++] = xy;
}
idx = 0;
triangles = (xycount / 2) - 2;
for (index = 2, idx = 0;idx < triangles;index += 2, ++idx){
a.v1[x] = polygon_vertices[0];
a.v1[y] = polygon_vertices[1];
a.v2[x] = polygon_vertices[index + 0];
a.v2[y] = polygon_vertices[index + 1];
a.v3[x] = polygon_vertices[index + 2];
a.v3[y] = polygon_vertices[index + 3];
triangle_area = area(a);
polygon_area += triangle_area;

}
printf("area=%.2f\t", polygon_area);
perim = perimeter(polygon_vertices, xycount);
printf("perimeter=%.2f\n", perim);

result[xycount] = printf("%.2f", polygon_area);
result[xycount] += printf("%.2f", perim);

if(strcmp(expected, result) == 0) {
printf("Arrays match.");
}
else{
printf("Arrays different\n");
};

}```

2. > result[xycount] = printf("%.2f", polygon_area);
> result[xycount] += printf("%.2f", perim);
What do you expect this to do?

What it isn't doing is building a string you can use with strcmp.

printf returns a int, which is the number of chars printed.

Maybe
sprintf(result,"%.2f%.2f",polygon_area, perim);

> a = *(triangle*)malloc(sizeof (triangle));
What's this?
The * right at the front is very suspect.

3. You should post a simplified complete program that can be compiled and that exhibits the problem. A sample of the input file would also help.

Code:
```result[xycount] = printf("%.2f", polygon_area);
result[xycount] += printf("%.2f", perim);```
If you're trying to build a string in "result" using the assignment operator, that won't work. "printf()" simply returns the number of characters written.

If you want to build strings with the value of variables, look into sprintf().

4. You can see the other part below, it is working and its showing always "Arrays diferent".

Code:
```#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
enum { x, y};
typedef struct triangle{
double v1[2];
double v2[2];
double v3[2];
} triangle;
double area(triangle a);
double perimeter(double* vertices, int size);
double side(double* p1, double* p2);
char expected[] = "80.0036.00";
char expected1[] = "48.0032.00";
char expected2[] = "61.5034.87";

char result[] = "";

int main()
{
int n, idx;
int triangles;
int index;
int xycount;
double xy;
double triangle_area;
double polygon_area;
double perim;
double polygon_vertices[50] = {0.0};
triangle a;
FILE* data;
char line[256];
char* token;
if ((data = fopen("C:\\Users\\CHK\\Desktop\\coordinates.txt", "r")) == NULL) {
fprintf(stderr, "can't open data file\n");
exit (EXIT_FAILURE);
}
while (fgets(line, sizeof (line), data)){
xycount = 0;
polygon_area = 0;
a = *(triangle*)malloc(sizeof (triangle));
memset(polygon_vertices, 0, sizeof (polygon_vertices));
line[strlen(line) - 1] = 0;
token = strtok(line, " ");
while (token != NULL){
xy = atof(token);
token = strtok(NULL, " ");
polygon_vertices[xycount++] = xy;
}
idx = 0;
triangles = (xycount / 2) - 2;
for (index = 2, idx = 0;idx < triangles;index += 2, ++idx){
a.v1[x] = polygon_vertices[0];
a.v1[y] = polygon_vertices[1];
a.v2[x] = polygon_vertices[index + 0];
a.v2[y] = polygon_vertices[index + 1];
a.v3[x] = polygon_vertices[index + 2];
a.v3[y] = polygon_vertices[index + 3];
triangle_area = area(a);
polygon_area += triangle_area;

}
printf("area=%.2f\t", polygon_area);
perim = perimeter(polygon_vertices, xycount);
printf("perimeter=%.2f\n", perim);

result[xycount] = printf("%.2f", polygon_area);
result[xycount] += printf("%.2f", perim);

if(strcmp(expected, result) == 0) {
printf("Arrays match.");
}
else{
printf("Arrays different\n");
};

}
fclose(data);
return 0;
}

/* calculate triangle area with Heron's formula */
double area(triangle a)
{
double s1, s2, s3, S, area;

s1 = side(a.v1, a.v2);
s2 = side(a.v2, a.v3);
s3 = side(a.v3, a.v1);
S = (s1 + s2 + s3) / 2;
area = sqrt(S*(S - s1)*(S - s2)*(S - s3));

return area;
}

/* calculate polygon perimeter */
double perimeter(double *vertices, int size)
{
int idx, jdx;
double p1[2], p2[2], pfirst[2], plast[2];
double perimeter;

perimeter = 0.0;
/* 1st vertex of the polygon */
pfirst[x] = vertices[0];
pfirst[y] = vertices[1];
/* last vertex of polygon */
plast[x] = vertices[size-2];
plast[y] = vertices[size-1];
/* calculate perimeter minus last side */
for(idx = 0; idx <= size-3; idx += 2)
{
for(jdx = 0; jdx < 4; ++jdx)
{
p1[x] = vertices[idx];
p1[y] = vertices[idx+1];
p2[x] = vertices[idx+2];
p2[y] = vertices[idx+3];
}
perimeter += side(p1, p2);
}
perimeter += side(plast, pfirst);

return perimeter;
}

/* calculate length of side */
double side(double *p1, double *p2)
{
double s1, s2, s3;

s1 = (p1[x] - p2[x]);
s2 = (p1[y] - p2[y]);
s3 = (s1 * s1) + (s2 * s2);

return sqrt(s3);
}```

5. Originally Posted by chenb
You can see the other part below, it is working and its showing always "Arrays diferent".

6. yes, thanks for your help. Im trying to fix this with that advice. But its strange, using sprintf, now I have 4 lines in the file and for the first two lines it is working now I get "Arrays match", but for the other two I get "Arrays diferent", Im trying to understand why, because they are equal too.

7. If you want more help, post your updated code.

8. I just change to sprintf(result,"%.2f%.2f",polygon_area, perim); The actual code is now this:

Code:
```#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
enum { x, y};
typedef struct triangle{
double v1[2];
double v2[2];
double v3[2];
} triangle;
double area(triangle a);
double perimeter(double* vertices, int size);
double side(double* p1, double* p2);
char expected[] = "80.0036.00";
char expected1[] = "48.0032.00";
char expected2[] = "61.5034.87";

char result[] = "";

int main()
{
int n, idx;
int triangles;
int index;
int xycount;
double xy;
double triangle_area;
double polygon_area;
double perim;
double polygon_vertices[50] = {0.0};
triangle a;
FILE* data;
char line[256];
char* token;
if ((data = fopen("C:\\Users\\CHK\\Desktop\\coordinates.txt", "r")) == NULL) {
fprintf(stderr, "can't open data file\n");
exit (EXIT_FAILURE);
}
while (fgets(line, sizeof (line), data)){
xycount = 0;
polygon_area = 0;
a = *(triangle*)malloc(sizeof (triangle));
memset(polygon_vertices, 0, sizeof (polygon_vertices));
line[strlen(line) - 1] = 0;
token = strtok(line, " ");
while (token != NULL){
xy = atof(token);
token = strtok(NULL, " ");
polygon_vertices[xycount++] = xy;
}
idx = 0;
triangles = (xycount / 2) - 2;
for (index = 2, idx = 0;idx < triangles;index += 2, ++idx){
a.v1[x] = polygon_vertices[0];
a.v1[y] = polygon_vertices[1];
a.v2[x] = polygon_vertices[index + 0];
a.v2[y] = polygon_vertices[index + 1];
a.v3[x] = polygon_vertices[index + 2];
a.v3[y] = polygon_vertices[index + 3];
triangle_area = area(a);
polygon_area += triangle_area;

}
printf("area=%.2f\t", polygon_area);
perim = perimeter(polygon_vertices, xycount);
printf("perimeter=%.2f\n", perim);

sprintf(result,"%.2f%.2f",polygon_area, perim);

if(strcmp(expected, result) == 0) {
printf("Arrays match.");
}
else{
printf("Arrays different\n");
};

}
fclose(data);
return 0;
}

/* calculate triangle area with Heron's formula */
double area(triangle a)
{
double s1, s2, s3, S, area;

s1 = side(a.v1, a.v2);
s2 = side(a.v2, a.v3);
s3 = side(a.v3, a.v1);
S = (s1 + s2 + s3) / 2;
area = sqrt(S*(S - s1)*(S - s2)*(S - s3));

return area;
}

/* calculate polygon perimeter */
double perimeter(double *vertices, int size)
{
int idx, jdx;
double p1[2], p2[2], pfirst[2], plast[2];
double perimeter;

perimeter = 0.0;
/* 1st vertex of the polygon */
pfirst[x] = vertices[0];
pfirst[y] = vertices[1];
/* last vertex of polygon */
plast[x] = vertices[size-2];
plast[y] = vertices[size-1];
/* calculate perimeter minus last side */
for(idx = 0; idx <= size-3; idx += 2)
{
for(jdx = 0; jdx < 4; ++jdx)
{
p1[x] = vertices[idx];
p1[y] = vertices[idx+1];
p2[x] = vertices[idx+2];
p2[y] = vertices[idx+3];
}
perimeter += side(p1, p2);
}
perimeter += side(plast, pfirst);

return perimeter;
}

/* calculate length of side */
double side(double *p1, double *p2)
{
double s1, s2, s3;

s1 = (p1[x] - p2[x]);
s2 = (p1[y] - p2[y]);
s3 = (s1 * s1) + (s2 * s2);

return sqrt(s3);
}```

9. Can you post the contents of your coordinates file as well?

10. Something I just noticed:

Code:
`line[strlen(line) - 1] = 0;`
This is generally not a safe approach. If the length is zero, you access elements out of bound.

See here for some alternatives.

11. Here's a strange piece of code:
Code:
`a = *(triangle*)malloc(sizeof (triangle));`
Consider what that does. It allocates an uninitialized chunk of memory big enough to hold a triangle, then copies it's uninitialized contents to a, then leaks the memory.

12. > char result[] = "";
This doesn't allocate enough space to store your result.
Specifically, it's only one byte containing \0.

Make this a longer string.

13. Thanks for your help. Do you know a alternative to that part?

14. Which part?

You can simply delete this line
a = *(triangle*)malloc(sizeof (triangle));

And maybe
char result[50];