如果我理解您在做什么,并且您需要确定左下坐标以及包围用户输入的 x、y 坐标的边界框的宽度和高度,那么您不需要在全部。您需要做的就是跟踪左下角和右下角坐标,并使用几个临时的double 值来捕获用户输入的最大 x、y 坐标,然后可以通过减去来设置宽度和高度最大值的左下角坐标。
(注意:您可能需要根据您使用的是普通笛卡尔坐标系(x,y 为中心为 0)还是屏幕坐标系(x,y 为 0)来调整比较在屏幕的左上角)。我们将把它留给你)
除非您检查返回,否则您无法正确使用任何输入功能。 scanf() 根据您在 format-string 中包含的 conversion-specifiers 返回发生的成功转换次数。如果在所有转换发生之前遇到EOF 或者如果发生 matching-failure,则它可能返回小于总数。 (例如,用户输入 "banana" 而不是坐标)。发生匹配失败时,将停止从stdin 提取字符,导致失败的字符留在stdin 中未读。 (只是等着你下次尝试输入时咬你)。
scanf() 在输入失败 上返回EOF(在第一次成功转换发生之前遇到EOF)。除了 matching 或 input 失败之外,您还必须处理用户输入的超出您要求的额外或无关字符(例如,用户输入 "10.2 13.8 and other nonsense"。否则下次输入尝试时将发生匹配失败。
有关每次调用scanf() 时必须检查的条件的更多详细信息,请参阅此问题的答案C For loop skips first iteration and bogus number from loop scanf。
实现边界框功能以及所需的验证非常简单。但是,使用scanf() 结束输入有点棘手。为了避免设置一些 MagicNumbers 让用户输入来表示完成,用户应该通过按 Ctrl + d(或 Ctrl + z 在 Windows 上)。然后您可以正常处理EOF,同时仍保留所有可能的输入。 (注意:使用推荐的输入法fgets()/sscanf(),用户只需在空行上按Enter即可表示完成)
考虑到这一点,您可以按如下方式实现您的功能:
#include <float.h> /* for `DBL_MAX` macro */
...
void readPointsFindBoundingBox (double *bottomLeftX, double *bottomLeftY,
double *widthp, double *heightp)
{
/* temp values for parameters, initialized to max/min of range */
double x = DBL_MAX, y = DBL_MAX, x_max = DBL_MIN, y_max = DBL_MIN;
*bottomLeftX = *bottomLeftY = DBL_MAX; /* initialize parameter values */
*widthp = *heightp = 0;
puts ("Press Ctrl+D (or Ctrl+z on windows twice) when done\n");
for (;;) { /* loop continually taking input */
int rtn; /* variable to save scanf() return */
fputs ("Enter coordinates (\"X Y\"): ", stdout); /* prompt for coordinates */
rtn = scanf ("%lf %lf", &x, &y); /* read input, save return */
if (rtn == EOF) { /* check if user done */
puts ("(input done)");
break;
}
/* empty remaining characters from stdin */
for (int c = getchar(); c != '\n'; c = getchar()) {}
/* validate EVERY user-input. 2 valid conversions required. */
if (rtn != 2) { /* handle matching-failure */
fputs (" error: invalid double values.\n", stderr);
continue;
}
if (x < *bottomLeftX) /* set bottomLeftX/Y as minimum coordinate */
*bottomLeftX = x; /* assumes lower-left is minimum coordinate */
if (y < *bottomLeftY) /* adjust '>' if Y increases as you go down */
*bottomLeftY = y;
if (x > x_max) /* track maximum bounding coordinates */
x_max = x; /* to calculate width, height */
if (y > y_max) /* adjust y compare if Y increases down */
y_max = y;
}
*widthp = x_max - *bottomLeftX; /* set width and height based on */
*heightp = y_max - *bottomLeftY; /* coordinates input by user */
}
(注意:这假定指针 double *bottomLeftX, double *bottomLeftY, double *widthp, double *heightp 都是简单的 double 值,返回到调用函数中,地址已传递给您的函数)
要测试您的功能,您可以写一个简短的main() 并将#include <stdio.h> 添加到顶部,例如
#include <stdio.h>
/* additional include and your function go here */
int main (void) {
double bottomleft, bottomright, width, height;
readPointsFindBoundingBox (&bottomleft, &bottomright, &width, &height);
printf ("\nBounding Box\n"
" Lower Left Coordinates (x, y): (%.2lf, %.2lf)\n"
" Height, Width (height, width): (%.2lf, %.2lf)\n",
bottomleft, bottomright, width, height);
}
使用/输出示例
$ ./bin/boundingboxfn
Press Ctrl+D (or Ctrl+z on windows twice) when done
Enter coordinates ("X Y"): 5.2 3
Enter coordinates ("X Y"): 9.1 -1
Enter coordinates ("X Y"): 2.2 3.3
Enter coordinates ("X Y"): .5 -.1
Enter coordinates ("X Y"): -1.4 8.1
Enter coordinates ("X Y"): my dog has fleas
error: invalid double values.
Enter coordinates ("X Y"): 1.1 1.1
Enter coordinates ("X Y"): 4 -2
Enter coordinates ("X Y"): (input done)
Bounding Box
Lower Left Coordinates (x, y): (-1.40, -2.00)
Height, Width (height, width): (10.50, 10.10)
如果您选择数字,该函数会提供正确的左下角坐标以及包围所有坐标所需的边界框的宽度和高度。 (回想一下前面关于如果您在屏幕坐标而不是正常的 X、Y 坐标系中工作时需要调整的注释,其中 X 和 Y 分别向右和向上增加)
如果我正确理解了您的问题,请告诉我,如果没有,请发表评论,我可以提供进一步的帮助。如果您对上述操作有任何疑问,请告诉我。