2015-04-23 101 views
-3

下面是我的程序,決定給予一定量的(X,Y)座標的多邊形的周長和麪積,但我似乎得到了錯誤的輸出,我不明白爲什麼。問題與程序輸出

的輸入是:

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 

隨着第一個條目是點(點)的數量,第二個輸入是所述多邊形的ID,之後是任何一組座標。

#include <stdio.h> 
#include <stdlib.h> 
#include <math.h> 

#define MAX_PTS 100 
#define MAX_POLYS 100 
#define END_INPUT 0 

struct Point { 
    double x, y; 
}; 

double getDistance(struct Point a, struct 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 polygon_area(int length, double x[], double y[]) { 
    double area = 0.0; 
    for (int i = 0; i < length; ++i) { 
     int j = (i + 1) % length; 
     area += (x[i] * y[j] - x[j] * y[i]); 
    } 
area = area/2; 
area = (area > 0 ? area : -1 * area); 

return (area); 
} 

int main(int argc, char *argv[]) { 
    int npoints, poly_id; 
    struct Point a, b; 

    if(scanf("%d %d", &npoints, &poly_id)) { 
     int iteration = 0; 
     scanf("%lf %lf", &a.x, &a.y); 
     struct Point initialPoint = a; 
     double perimeter = 0; // i start with 0 value of parameter.  
     for (iteration = 1; iteration < npoints; ++iteration) { 
      scanf("%lf %lf", &b.x, &b.y); // take input for new-point. 
      perimeter += getDistance(a, b); // add the perimeter. 
     // for next iteration, new-point would be first-point in getDistance 
      a = b; 
     } 
     // now complete the polygon with last-edge joining the last-point 
     // with initial-point. 
     perimeter += getDistance(a, initialPoint); 

     printf("First polygon is %d\n", poly_id); 
     printf("perimeter = %2.2lf m\n", perimeter); 

     scanf("%d %d", &npoints, &poly_id); 
     double x[MAX_PTS], y[MAX_PTS]; 
     double area = 0; 
     for (iteration = 0; iteration < npoints; ++iteration) { 
      scanf("%lf %lf", &(x[iteration]), &(y[iteration])); 
     } 
     area = polygon_area(npoints, x, y); 

     printf("First polygon is %d\n", poly_id); 
     printf("area = %2.2lf m^2\n", area); 

    } else if(scanf("%d", &npoints)==0) { 
     exit(EXIT_SUCCESS); 
    } 

    return 0; 
} 

我的輸出總是收到是:

First polygon is 12867 
perimeter = 10.24 m 
First polygon is 15643 
area = 19.59 m^2 

但我想輸出是:

First polygon is 12867 
perimeter = 10.24 m 
First polygon is 12867 
area = 4.50 m^2 

或者:

First polygon is 12867 
perimeter = 10.24 m 
area = 4.50 m^2 

想,如果有人可以理解可以指出我去過的地方ne錯了。

+4

我建議學習如何使用調試器。這個想法是一行一行地通過你的代碼,並檢查變量,直到你發現錯誤。另一種方法是在關鍵點用'printf'輸出值。 – dandan78

+0

在計算第一個多邊形區域之前,您正在讀取第二個多邊形。將第一個多邊形的座標讀入一個數組,以便您可以執行周長和麪積。 – JS1

+0

你的問題標題說,當輸出不是實際問題時,輸出存在一些問題。問題顯然是代碼而不是輸出問題。當有人閱讀問題標題時,這不是他們所期望的問題。 –

回答

0

如果您還沒有整理出來呢,你的問題是顯而易見的。你讀第一個多邊形的數據,然後你計算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); 

然後,莫名其妙地,你在計算面積之前,閱讀你的第二個多邊形數據使用第二個多邊形的數據的第一個多邊形的區域有點令人迷惑。

在讀取下一個數據之前,您需要做的是計算每個多邊形的perimeterarea。而不是你的代碼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; 
} 

但是,爲什麼不寫你的代碼來讀取數據文件,並消除了容易出錯的用戶輸入的輸入程序?這需要一點時間,但並不難。這樣你可以完全分離代碼的輸入和處理功能。

即釋放你實際上集中在鋪設代碼的處理部出來以邏輯方式,而不是具有與用戶輸入灑處理邏輯。以下是將輸入與代碼邏輯分離的示例,可以幫助保持代碼清潔和可讀性。它在開始第一次計算之前將所有數據讀入一個結構數組中。

當你把你的代碼分成邏輯功能,它使保持像perimeterarea調整功能單一的邏輯簡單的事情任何個人計算。看看下面,讓我知道,如果您有任何疑問:

#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