您忽略了来自scanf() 的返回,它告诉您输入的信息对于转换 (%d) 是否准确。如果它不准确,您必须进行错误恢复,这对于scanf() 来说并不是特别容易。大多数人会选择“读取一行输入然后解析它”的方法,错误恢复更简单。
我知道返回值在错误检查中是必不可少的,但是我如何扫描它的数字或字母呢?我可以说 if (input!=(integers)) 或类似的东西吗?
这就是人们不使用scanf() 的原因。如果将数据行放入缓冲区(字符数组)中,则可以根据需要随时检查数组的内容。如果您使用scanf(),则在scanf() 确定它有错误之前,您没有可靠的机会处理数据。
<ctype.h> 中的函数(通常也可用作宏)允许您对字符进行分类。 <stdlib.h> 中的函数提供了从字符串到各种整数的可靠转换。
所以,你可以考虑做这样的事情:
char buffer[256];
while (fgets(buffer, sizeof(buffer), stdin))
{
...check contents of buffer using isdigit() etc...
...or just plough ahead with...
long value;
char *end;
errno = 0;
value = strtol(buffer, &end, 0);
if (errno != 0 || (*end != '\0' && !isspace(*end))
...diagnose problems...
}
目前这段代码有点超出我的范围......有没有更简单的方法?
好吧,我想你可以使用atoi() 代替strtol(),这样可以简化错误处理(因为它不太精确):
char buffer[256];
while (fgets(buffer, sizeof(buffer), stdin))
{
int value = atoi(buffer);
if (value == 0)
{
puts("zero read - exiting loop");
break;
}
}
没有比这更简单的了。我不知道您认为之前解决方案的哪一部分超出了您的范围。在我看来,替代方案要复杂得多,包括一次读取一个字符并保存数字并拒绝非数字:
char buffer[256];
char *dst = buffer;
int c;
int value;
while ((c = getchar()) != EOF)
{
if (isdigit(c))
{
*dst++ = c; /* Ignoring buffer overflow - bad! */
}
else if (isspace(c))
{
*dst = '\0';
value = atoi(buffer);
break;
}
else
{
printf("Unexpected character '%c'!\n", c);
}
}
等等。该代码中有各种问题需要解决 - 比如在错误字符后重置指针,避免缓冲区溢出,处理数字上的符号,以及......好吧,我宁愿把各种东西留给例程比如fgets()和strtol()。