检查意外用户输入的方法

时间:2017-05-18 13:47:31

标签: c validation input

我了解到人们永远不应该信任用户的输入。在处理之前检查它已成为一种习惯。我几乎总是使用这种类型的函数,并且经常想知道这两个版本之间是否存在差异

以下是我的检查功能的简单示例:

版本1

int checkASCII(char c) // Here we check, print error and return if it succeeded or not
{
    if (!isascii(c))
    {
        fprintf(stderr, "Error. Not an ASCII character.\n.");
        return 1;
    }
    if (!isdigit(c))
    {
        fprintf(stderr, "Error. Not a number.\n.");
        return 1;
    }
    // potentially more checks
    return 0;
}

int printASCIINumber() // So that here we just have to verify the success
{
   char c;
   c = getc(stdin);
   if (checkASCII(c))
      putc(c, stdout);
   else return 1;
   return 0;
}

版本2

int checkASCII(char c) // Here we just check errors regardless of what failed
{
    if (!isascii(c))
      return 1;
    if (!isdigit(c)
      return 1;
    ... // potentially more checks
    return 0;
}

int printASCIINumber() // And here we verify success and print a general error message
{
   char c;
   c = getc(stdin);
   if (checkASCII(c))
      putc(c, stdout);
   else 
   {
      fprintf(stderr, "Error. Please input an ASCII number.\n");
      return 1;
   }
   return 0;
}

如果有任何客观改进,我也不反对。感谢。

1 个答案:

答案 0 :(得分:3)

首先:您的返回值与之后的支票不符。如果您认为结果是错误代码,0表示成功,那么您必须通过if(!checkASCII(c))进行测试 - 如果您认为结果是布尔值,那么您需要反转返回的值。在这种情况下,我建议使用<stdbool.h>,将返回类型更改为bool,并将函数重命名为isASCII。这会使你的意图更加明显。

比较你的两个版本,我会说两者都不优于另一个版本 - 而是取决于你编程的情况。

想象一下,你正在写一些通用库。然后我当然更喜欢变体2,因为你不知道是谁需要使用你的库的控制台输出 - 或者控制台是否可用(linux守护进程,windows服务等)。无论出于何种原因,用户可能想要使用自己的日志记录工具......

另一方面,如果您只编写程序中使用的辅助函数,则变体1可以更方便:

  • 您可以直接在函数中直接提供更细粒度的输出 - 无需在函数外部评估某些错误或返回值(这可能是库函数提供有关错误的更多信息的方式)
  • 方便,特别是如果经常调用您的检查功能,以便能够在调用测试功能时依赖已经完成的日志记录,这样您就可以继续使用代码了。