如何根据C中函数中函数的输入退出while循环?

时间:2016-03-17 02:56:22

标签: c

我的main函数中有一个while循环,它调用一个用户定义的函数,该函数调用另一个用户定义的函数,该函数调用scanf来读取一对double值。我希望我的程序在输入非数字时结束。我的函数返回结构,而不是0/1。有没有办法传递一个错误的scanf返回来打破我的while循环?

我可以声明一个全局变量并将其分配给scanf语句,然后在if函数中对该变量进行main语句吗? 或者我是否必须更改我的函数以返回int(0/1)并通过引用传递我的结构?

这可能是一个非常糟糕的解释,所以这里是我的问题所涉及的部分的代码......该程序是读取一个矩形(左下角和右上角)和一个圆圈,并说是否他们的区域重叠。我希望在while函数的main循环中暂停......

typedef struct{double x,y;} point;
typedef struct{point a,b,c,d;} rectangle;
typedef struct{point o; double r;} circle;

point readPoint(){
    point p;
    scanf("%lf%lf", &p.x, &p.y);     //type "quit"
    return p;
}

rectangle readRectangle(){
    rectangle r;
    r.c=readPoint();
    r.b=readPoint();
    r.a.x=r.c.x;
    r.a.y=r.b.y;
    r.d.x=r.b.x;
    r.d.y=r.c.y;
    return r;
}

int main(void) {
    int a=0;
    rectangle r;
    circle c;

    while(1){
        printf("Enter rectangle:");
        r=readRectangle();            //break loop here if quit is entered
        printf("Enter circle:");
        c=readCircle();
        a=overlap(r, c);
        if (a==1)
            printf("The rectangle and the circle overlap.\n\n");
        else
            printf("The rectangle and the circle do not overlap.\n\n");
    }
    printf("Program completed normally.");
    return EXIT_SUCCESS;
}

4 个答案:

答案 0 :(得分:2)

重新定义readPoint()readRectangle()功能,如下所示:

#include <stdbool.h>
#include <stdio.h>

typedef struct { double x, y; } point;
typedef struct { point a, b, c, d; } rectangle;   

bool readPoint(point *p)
{
    if (scanf("%lf%lf", &p->x, &p->y) != 2)
        return false;
    return true;
}

bool readRectangle(rectangle *r)
{
    if (!readPoint(&r->c) || !readPoint(&r->b))
        return false;
    r->a.x = r->c.x;
    r->a.y = r->b.y;
    r->d.x = r->b.x;
    r->d.y = r->c.y;
    return true;
}

int main(void)
{
    while (1)
    {
        rectangle r;
        printf("Enter rectangle: ");
        if (!readRectangle(&r))
            break;   
        …
    }
    return 0;
}

这是您概述的策略之一 - 它可能是最好的。您可以继续返回结构并通过指针(point readPoint(int *status))传递状态变量 - 它可以工作,但这不是传统的方法。

更加宽松的技巧将使用来自setjmp()的{​​{1}}和longjmp();您在<setjmp.h>函数中调用setjmp(),并在输入代码检测到问题时调用main()。我不推荐这个 - 只是概述一个替代方案。

是的,您可以将longjmp()缩写为:

readPoint()

答案 1 :(得分:1)

因为这是一个不好的想法,我将提供这个问题的字面答案。是的,你可以这样做。你最好有一个很好的理由这样做,因为或者其他人会惊恐地尖叫你所创造的代码。

#include <stdio.h>
#include <setjmp.h>

typedef struct{double x,y;} point;
typedef struct{point a,b,c,d;} rectangle;
typedef struct{point o; double r;} circle;

point readPoint(jmp_buf jmp){
    point p;
    if (scanf("%lf%lf", &p.x, &p.y) != 2)     /*type "quit"*/
        longjmp(jmp, 1); /* returns to setjmp() call with 1 */
    return p;
}

rectangle readRectangle(jmp_buf jmp){
    rectangle r;
    r.c=readPoint(jmp);
    r.b=readPoint(jmp);
    r.a.x=r.c.x;
    r.a.y=r.b.y;
    r.d.x=r.b.x;
    r.d.y=r.c.y;
    return r;
}

int main(void) {
    jmp_buf jmp;
    if (setjmp(jmp) == 0) {
        while(1){
            int a=0;
            rectangle r;
            circle c;
            printf("Enter rectangle:");
            r=readRectangle(jmp);
            printf("Enter circle:");
            c=readCircle(jmp);
            a=overlap(r, c);
            if (a==1)
                printf("The rectangle and the circle overlap.\n\n");
            else
                printf("The rectangle and the circle do not overlap.\n\n");
        }
    }
    printf("Program completed normally.");
    return EXIT_SUCCESS;
}

答案 2 :(得分:0)

我希望你的readPoint方法返回0/1表示读取成功或失败,然后通过引用将结果传回。

这样可以保持数据清洁,而不是为每个结果传递一个isBadData标志。

答案 3 :(得分:0)

您需要在readPoint()中进行一些修改。

point readPoint(){
int s;
point p;
s=scanf("%lf%lf", &p.x, &p.y);
if(s==0) exit(EXIT_FAILURE);
return p;
}

如果未输入值,或者它们不符合格式,则为s=0,因为它是scanf()返回的值。有关更多信息,请访问http://www.cplusplus.com/reference/cstdio/scanf/

包含stdlib.h头文件以使用退出功能。