我正在尝试在范围和类型整数之间验证输入。目前我有以下代码。所需的范围是X为0-100,Y为0-50。
for(loop=0;loop<3;loop++){
printf("\n\nEnter MAGENTA X coordinate from 0 to 100:\n");
scanf("%d",&mg[loop].x);
printf("\nEnter MAGENTA Y coordinate from %d to 50:\n");
scanf("%d",&mg[loop].y);
}
我需要用户选择提前结束输入,可能是输入“end”或类似的东西。然后应该移动到黄色的下一个颜色。
是否有人知道如何使用scanf
实现此目的?
------ ----- EDIT
我已实现以下内容,默认为"failure"
。我将句柄增加到2
并收到错误end is being use without being initialized
。
for(loop=0;loop<3;loop++){
printf("\n\nEnter MAGENTA X coordinate from 0 to 100:\n");
if(scanf("%d%c",&mg[loop].x) != 1 || end !='\n')
printf("failure");
else
printf("\nEnter MAGENTA Y coordinate from 0 to 50:\n");
scanf("%d",&mg[loop].y); /*Use the same validation here as above*/
}
答案 0 :(得分:0)
你可以使用scanf,没关系。为什么不? scanf返回成功读取的项目数,因此0表示格式错误。之后,你想在要求另一个输入之前丢弃剩余的输入。
然后根据边界测试读取变量。
您可以为用户希望退出指定一个特殊值,也许某些字符串如“exit”,这会使scanf失败,然后检查它是否“退出”。当你想退出循环时,break命令会很方便。
答案 1 :(得分:0)
您可以使用scanf()
但错误报告往往比较棘手。最小化您的代码:
for (loop = 0; loop < 3; loop++)
{
int rc;
printf("\n\nEnter YELLOW X coordinate from 0 to 100:\n");
while ((rc = scanf("%d", &ylw[loop].x)) == 1 &&
(ylw[loop].x < 0 || ylw[loop].y > 100)
printf("Enter a value between 0 and 100\n");
if (rc != 1)
{
fprintf(stderr, "Error reading x-value.\n");
break;
}
printf("\nEnter YELLOW Y coordinate from 0 to 50:\n");
while ((rc = scanf("%d", &ylw[loop].y)) == 1 &&
(ylw[loop].x < 0 || ylw[loop].y > 50)
printf("Enter a value between 0 and 50\n");
if (rc != 1)
{
fprintf(stderr, "Error reading y-value.\n");
break;
}
}
但是,这种重复会激发一个功能 - 虽然它具有适度复杂的界面:
int prompt_for(const char *what, int min, int max, int err)
{
int value;
int rc;
printf("\nEnter %s from %d to %d:", what, min, max);
while ((rc = scanf("%d", &value)) == 1 && (value < min || value > max))
printf("Enter a value between %d and %d\n", min, max);
if (rc != 1)
{
fprintf(stderr, "Error reading %s.\n", what);
return err;
}
return value;
}
样品使用:
for (loop = 0; loop < 3; loop++)
{
ylw[loop].x = prompt_for("YELLOW X coordinate", 0, 100, -1);
if (ylw[loop].x == -1)
break;
ylw[loop].y = prompt_for("YELLOW Y coordinate", 0, 50, -1);
if (ylw[loop].y == -1)
break;
}
如果您使用fgets()
和sscanf()
,则可以使用:
int prompt_for(const char *what, int min, int max, int err)
{
int value;
int rc;
char line[4096];
printf("\nEnter %s from %d to %d:", what, min, max);
while (fgets(line, sizeof(line), stdin) != 0 &&
(rc = sscanf(line, "%d", &value)) == 1 &&
(value < min || value > max))
printf("Enter a value between %d and %d\n", min, max);
if (rc != 1)
{
fprintf(stderr, "Error reading %s.\n", what);
return err;
}
return value;
}
尽管如此,这并没有充分利用fgets()
;当您想要在一行上有多个数据项时,它会得分,因为这样您就可以报告输入的整行。
警告:此代码均未编译
答案 2 :(得分:0)
如果你想强制每个输入都在它自己的输入行上(在交替提示和从stdin读取时是可取的),我建议先将一行读入临时行缓冲区,然后用{{ 1}}。然后检查输入在最后一步是否有效。
因为这可能会使你的代码变得混乱,你可能会为此调整自己的功能:
sscanf
然后您可以这样读取您的坐标:
/*
* Read an integer from stdin. Repeat until a valid number between
* lo and hi has been given. Returns 0 when a number was read and
* -1 when the input has run out.
*/
int read_int(int *x, int lo, int hi)
{
char buf[80];
char c;
for (;;) {
if (fgets(buf, sizeof(buf), stdin) == NULL) return -1;
if (sscanf(buf, "%d %c", x, &c) != 1 || *x < lo || *x > hi) {
printf("Please enter a single value between %d and %d.\n",
lo, hi);
} else {
break;
}
}
return 0;
}
如果用户键入文件名字符(Ctrl-D un Unix,Windows上为Ctrl-Z),则可以缩短坐标数。如果您想使用某个关键字结束输入,请说&#34;结束&#34;,您可以通过读取字符串并首先检查来将其添加到您的函数中:
struct Coord ylw[3] = {{0, 0}};
int i;
for(i = 0; i < MAX; i++) {
printf("\n\nEnter YELLOW X coordinate #%d from 0 to 100:\n", i);
if (read_int(&ylw[i].x, 0, 100) < 0) break;
printf("\nEnter YELLOW Y coordinate #%d from 0 to 50:\n", i);
if (read_int(&ylw[i].y, 0, 50) < 0) break;
}
(从字符串中查找字符串似乎是多余的,但这样用户可以键入&#34; end&#34;在一些空格之后。您还可以使用不区分大小写的字符串比较函数。)