我的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;
}
答案 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头文件以使用退出功能。