问题与程序输出 [英] Issue with program output

查看:109
本文介绍了问题与程序输出的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

下面是我的计划,决定给予一定数额的(X,Y)坐标的多边形的周长和面积,但我似乎得到了错误的输出,我不明白为什么。

Below is my program that determines the perimeter and area of a polygon given a certain amount of (x,y) coordinates but I seem to be getting the wrong output and I can't see why.

输入是:

  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的数量,之后任何事情都是一组坐标。

With the first entry being the number of points (points) and the second entry being the polygon ID, anything after that is a set of coordinates.

#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;
}

我的输出总是收到的是:

My output I keep getting is:

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

但我想要的输出是:

But the output I want is:

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

将AP preciated如果有人可以只点出在哪里我已经错了。

Would be appreciated if someone could just point out where I've gone wrong.

推荐答案

如果您还没有整理出来呢,你的问题是显而易见的。你读第一个多边形的数据,然后你计算周边

If you haven't sorted it out yet, your problem is obvious. You read the data for the first polygon and then you calculate the perimeter:

    perimeter += getDistance(a, initialPoint);

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

然后,莫名其妙地,你在计算领域之前,阅读你的第二个多边形数据:

Then, inexplicably, you read data for your second polygon before calculating the area:

    scanf("%d %d", &npoints, &poly_id);
    double x[MAX_PTS], y[MAX_PTS];
    double area = 0;
<snip>
    area = polygon_area(npoints, x, y); 

您如何期望获得该地区使用数据的第二个多边形的第一个多边形有点扑朔迷离。

How you expect to get the area for the first polygon using data for the second polygon is a bit bewildering.

您需要做的是计算两个周边区域每个多边形读取数据之前下一个。而不是你的如果 code块,你通常会提示输入多边形数量来处理和那么这样做:

What you need to do is calculate both the perimeter and the area for each polygon before reading the data for the next. Rather than your if block of code, you would usually prompt to enter the number of polygons to process and then do something like:

for (i = 0; i < npolys; i++)
{
    <read data for poly>
    <calculate perimeter>
    <calculate area>
    <display results>
}

接下来,当你从一个用户期望的数据,提示它。不要只留给用户看着闪烁的光标想知道如果你的程序挂起,等等。一个简单的的printf 要求的点数和多边形ID工作正常。然后,像提示输入每个x / y对走一段很长的方式来消除混乱。考虑到所有上述考虑,你的code可以重新写为:

Next, when you expect data from a user, prompt for it. Don't just leave the user looking at a blinking cursor wondering if your program hung, etc.. A simple printf asking for the number of points and polygon id works fine. Then a like prompt to enter each x/y pair goes a long way to eliminating confusion. Taking all the above into consideration, your code could be re-written as:

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;
}

但是,为什么不写一个程序输入您的code读取数据文件,并消除了容易出错的用户输入?这需要一点时间,但它并不难。这样,你可以完全分离你的code的输入和处理功能。

But why not write an input routine for your code to read your data file and eliminate the error prone user input? It takes a little time, but it's not hard. That way you can completely separate the input and processing functions of your code.

这将释放你真正专注于您的铺设code OUT的处理部分以逻辑的方式,而不是让用户输入洒处理逻辑。以下是如何从code的逻辑分离输入,可以帮助保持你的code清洁和可读性的例子。它开始第一计算之前读取的所有数据进结构的阵列

That frees you to actually concentrate on laying the processing part of your code out in a logical manner, instead of having the processing logic sprinkled with user input. The following is an example of how separating input from the logic of your code can help keep your code clean and readable. It reads all data into an array of structures before beginning the first computation.

当你把你的code分成逻辑功能,它使保持像周边任何个人计算或区域调整的单一功能的逻辑的一个简单的事情。看看下面,让我知道,如果你有任何问题:

When you keep your code separated into logical function, it makes maintaining any individual computation like perimeter or area a simple matter of adjusting the logic of a single function. Take a look at the following and let me know if you have questions:

#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

这篇关于问题与程序输出的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆