如果您還沒有整理出來呢,你的問題是顯而易見的。你讀第一個多邊形的數據,然後你計算perimeter
:
scanf("%d %d", &npoints, &poly_id);
double x[MAX_PTS], y[MAX_PTS];
double area = 0;
<snip>
area = polygon_area(npoints, x, y);
你怎麼指望得到:
perimeter += getDistance(a, initialPoint);
printf("First polygon is %d\n", poly_id);
printf("perimeter = %2.2lf m\n", perimeter);
然後,莫名其妙地,你在計算面積之前,閱讀你的第二個多邊形數據使用第二個多邊形的數據的第一個多邊形的區域有點令人迷惑。
在讀取下一個數據之前,您需要做的是計算每個多邊形的perimeter
和area
。而不是你的代碼if
塊,你通常會提示輸入number of polygons
處理,然後做一些事情,如:
for (i = 0; i < npolys; i++)
{
<read data for poly>
<calculate perimeter>
<calculate area>
<display results>
}
接下來,當你從一個用戶期望的數據,進行提示。不要只讓用戶在看一個閃爍的光標想知道如果你的程序掛起,等等。一個簡單的printf
要求的點數和多邊形ID工作正常。然後,類似提示輸入每個x/y對可以消除混淆。考慮到所有上述考慮,你的代碼可以重新寫爲:
int main (void) {
size_t npoints, poly_id;
size_t npolys = 0;
size_t it = 0;
struct Point a, b;
printf ("\nNumber of polygons to enter: ");
scanf (" %zu", &npolys);
for (it = 0; it < npolys; it++)
{
double x[MAX_PTS], y[MAX_PTS];
double perimeter = 0;
double area = 0;
size_t iter = 0;
printf ("\nEnter npoints & poly_id : ");
scanf("%zu %zu", &npoints, &poly_id);
printf ("Enter the first point X & Y: ");
scanf("%lf %lf", &a.x, &a.y);
x[iter] = a.x;
y[iter] = a.y;
struct Point initialPoint = a;
for (iter = 1; iter < npoints; ++iter)
{
printf (" next point X & Y: ");
scanf("%lf %lf", &b.x, &b.y); /* input for new-point. */
x[iter] = b.x;
y[iter] = b.y;
perimeter += getDistance(a, b); /* add the perimeter. */
a = b; /* new-pt is first-pt */
}
/* complete polygon joining the last-point with initial-point. */
perimeter += getDistance (b, initialPoint);
area = polygon_area (npoints, x, y);
printf("\nPolygon %zu is %zu\n", it, poly_id);
printf("perimeter = %2.2lf m\n", perimeter);
printf(" area = %2.2lf m^2\n", area);
}
return 0;
}
但是,爲什麼不寫你的代碼來讀取數據文件,並消除了容易出錯的用戶輸入的輸入程序?這需要一點時間,但並不難。這樣你可以完全分離代碼的輸入和處理功能。
即釋放你實際上集中在鋪設代碼的處理部出來以邏輯方式,而不是具有與用戶輸入灑處理邏輯。以下是將輸入與代碼邏輯分離的示例,可以幫助保持代碼清潔和可讀性。它在開始第一次計算之前將所有數據讀入一個結構數組中。
當你把你的代碼分成邏輯功能,它使保持像perimeter
或area
調整功能單一的邏輯簡單的事情任何個人計算。看看下面,讓我知道,如果您有任何疑問:
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <math.h>
#define MAXPTS 100
#define MAXPOLYS 100
typedef struct point {
double x, y;
} point;
typedef struct polygon {
size_t sz;
size_t id;
point *vertex;
} polygon;
double get_distance (point a, point b);
double poly_perim (polygon a);
double polygon_area (polygon pg);
polygon *read_data (char *fn);
int main (int argc, char **argv)
{
if (argc < 2) {
fprintf (stderr, "error: insufficient input, usage: %s filename\n", argv[0]);
return 1;
}
size_t it = 0;
size_t idx = 0;
polygon *pg = read_data (argv[1]);
if (!pg) return 1;
while (pg[idx].sz)
{
printf ("\n id: %zu points: %zu perimeter: %6.2lf area: %6.2lf\n\n",
pg[idx].id, pg[idx].sz, poly_perim (pg[idx]), polygon_area (pg[idx]));
for (it = 0; it < pg[idx].sz; it++)
printf (" %5.2lf %5.2lf\n", pg[idx].vertex[it].x, pg[idx].vertex[it].y);
idx++;
}
return 0;
}
double get_distance (point a, point b)
{
double distance;
distance = sqrt ((a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y));
return distance;
}
double poly_perim (polygon a)
{
int i = 0;
double perim = get_distance (a.vertex[0], a.vertex[a.sz -1]);
for (i = 1; i < a.sz; i++)
perim += get_distance (a.vertex[i-1], a.vertex[i]);
return perim;
}
double polygon_area (polygon pg)
{
double area = 0.0;
int i = 0;
for (i = 0; i < pg.sz; ++i)
{
int j = (i + 1) % pg.sz;
area += (pg.vertex[i].x * pg.vertex[j].y - pg.vertex[j].x * pg.vertex[i].y);
}
area /= 2.0;
area = area > 0 ? area : -1 * area;
return area;
}
polygon *read_data (char *fn)
{
char *ln = NULL;
size_t n = 0;
size_t it = 0;
size_t idx = 0;
ssize_t nchr = 0;
FILE *fp = NULL;
polygon *pg = NULL;
if (!(fp = fopen (fn, "r"))) {
fprintf (stderr, "%s() error: file open failed '%s'.\n", __func__, fn);
exit (EXIT_FAILURE);
}
if (!(pg = calloc (MAXPOLYS, sizeof *pg))) {
fprintf (stderr, "%s() error: virtual memory allocation failed.\n", __func__);
exit (EXIT_FAILURE);
}
while ((nchr = getline (&ln, &n, fp)) != -1)
{
char *p = ln;
char *ep = NULL;
long lnum = 0;
double dnum = 0;
errno = 0;
lnum = strtol (p, &ep, 10);
if (errno == 0 && (p != ep && lnum != 0))
pg[idx].sz = (size_t)lnum;
else {
fprintf (stderr, "%s() error: file read failure '%s'.\n", __func__, fn);
exit (EXIT_FAILURE);
}
p = ep;
errno = 0;
lnum = strtol (p, &ep, 10);
if (errno == 0 && (p != ep && lnum != 0))
pg[idx].id = (size_t)lnum;
else {
fprintf (stderr, "%s() error: file read failure '%s'.\n", __func__, fn);
exit (EXIT_FAILURE);
}
pg[idx].vertex = calloc (pg[idx].sz, sizeof *(pg[idx].vertex));
if (!pg[idx].vertex) {
fprintf (stderr, "%s() error: virtual memory allocation failed.\n", __func__);
exit (EXIT_FAILURE);
}
for (it = 0; it < pg[idx].sz; it++)
{
p = ep;
errno = 0;
dnum = strtod (p, &ep);
if (errno == 0 && (p != ep && lnum != 0))
pg[idx].vertex[it].x = dnum;
else {
fprintf (stderr, "%s() error: file read failure '%s'.\n", __func__, fn);
exit (EXIT_FAILURE);
}
p = ep;
errno = 0;
dnum = strtod (p, &ep);
if (errno == 0 && (p != ep && lnum != 0))
pg[idx].vertex[it].y = dnum;
else {
fprintf (stderr, "%s() error: file read failure '%s'.\n", __func__, fn);
exit (EXIT_FAILURE);
}
}
idx++;
if (idx == MAXPOLYS) {
fprintf (stderr, "%s() warning: MAXPOLYS reached in file '%s'.\n", __func__, fn);
break;
}
}
fclose (fp);
if (ln) free (ln);
return pg;
}
輸入
$ cat dat/poly.txt
3 12867 1.0 2.0 1.0 5.0 4.0 5.0
5 15643 1.0 2.0 4.0 5.0 7.8 3.5 5.0 0.4 1.0 0.4
輸出
$ ./bin/poly dat/poly.txt
id: 12867 points: 3 perimeter: 10.24 area: 4.50
1.00 2.00
1.00 5.00
4.00 5.00
id: 15643 points: 5 perimeter: 18.11 area: 19.59
1.00 2.00
4.00 5.00
7.80 3.50
5.00 0.40
1.00 0.40
我建議學習如何使用調試器。這個想法是一行一行地通過你的代碼,並檢查變量,直到你發現錯誤。另一種方法是在關鍵點用'printf'輸出值。 – dandan78
在計算第一個多邊形區域之前,您正在讀取第二個多邊形。將第一個多邊形的座標讀入一個數組,以便您可以執行周長和麪積。 – JS1
你的問題標題說,當輸出不是實際問題時,輸出存在一些問題。問題顯然是代碼而不是輸出問題。當有人閱讀問題標題時,這不是他們所期望的問題。 –