【问题标题】:How to prevent users from typing incorrect inputs?如何防止用户输入错误的输入?
【发布时间】:2010-05-08 18:59:51
【问题描述】:

程序要求输入一个数字。如果用户键入的不是数字,程序应该循环scanf() 函数。

代码是,

 do{
     printf("Enter row number\n");
     scanf("%d",&row);
  }while(row>='a' && row<='z');

但是上面的代码不起作用。我在输入字母时不断收到错误消息。我尝试围绕它进行操作,整个过程无限循环。

有什么建议吗?

此外,我如何告诉C Compiler 不要中断循环,除非输入是整数?

【问题讨论】:

  • 防止用户输入错误的唯一万无一失的方法就是没有任何用户!
  • 你为什么读char%d
  • @dboarman,这是 C @Kenny,我要求用户输入行数,这只是一个示例
  • 你是在告诉它在他们输入字母时拿起一个数字......这没有任何意义。

标签: c error-handling


【解决方案1】:

您忽略了来自scanf() 的返回,它告诉您输入的信息对于转换 (%d) 是否准确。如果它不准确,您必须进行错误恢复,这对于scanf() 来说并不是特别容易。大多数人会选择“读取一行输入然后解析它”的方法,错误恢复更简单。


我知道返回值在错误检查中是必不可少的,但是我如何扫描它的数字或字母呢?我可以说 if (input!=(integers)) 或类似的东西吗?

这就是人们不使用scanf() 的原因。如果将数据行放入缓冲区(字符数组)中,则可以根据需要随时检查数组的内容。如果您使用scanf(),则在scanf() 确定它有错误之前,您没有可靠的机会处理数据。

&lt;ctype.h&gt; 中的函数(通常也可用作宏)允许您对字符进行分类。 &lt;stdlib.h&gt; 中的函数提供了从字符串到各种整数的可靠转换。

所以,你可以考虑做这样的事情:

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()

【讨论】:

  • 感谢您的回复,是的,我知道返回值在错误检查中是必不可少的,但是如何扫描它的数字或字母?我可以说 if (input!=(integers)) 或类似的东西吗?
  • 感谢您的解释,但这段代码目前有点超出我的范围......有没有更简单的方法?
  • @Zazu:讲解完整,代码简单。您需要重新阅读它,直到您理解它为止。例如,此答案中的第三个代码块是如何做到但不应该这样做。第二个代码块调用了自 1977 年以来已被充分记录的两个函数。如果您无法了解 fgets 和 atoi 以及 while 循环的结构,那么是的,您不合群,应该了解编程。我们不会在这里为您编写代码,也无法让您阅读已编写的内容。
  • @Zazu:另外,在 Stack Overflow 上重新提出您已经提出的问题有点令人不悦:stackoverflow.com/questions/2796108/…
【解决方案2】:

您需要读取字符,然后确定该字符是否为数字并根据需要进行转换。您还需要检查一些特殊字符,例如 'q' 或在您完成输入字符后让您跳出循环的东西。

【讨论】:

    猜你喜欢
    • 2013-11-13
    • 2011-06-16
    • 2012-05-28
    • 2013-12-13
    • 2019-09-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多