我了解到人们永远不应该信任用户的输入。在处理之前检查它已成为一种习惯。我几乎总是使用这种类型的函数,并且经常想知道这两个版本之间是否存在差异。
以下是我的检查功能的简单示例:
版本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;
}
如果有任何客观改进,我也不反对。感谢。
答案 0 :(得分:3)
首先:您的返回值与之后的支票不符。如果您认为结果是错误代码,0表示成功,那么您必须通过if(!checkASCII(c))
进行测试 - 如果您认为结果是布尔值,那么您需要反转返回的值。在这种情况下,我建议使用<stdbool.h>
,将返回类型更改为bool
,并将函数重命名为isASCII
。这会使你的意图更加明显。
比较你的两个版本,我会说两者都不优于另一个版本 - 而是取决于你编程的情况。
想象一下,你正在写一些通用库。然后我当然更喜欢变体2,因为你不知道是谁需要使用你的库的控制台输出 - 或者控制台是否可用(linux守护进程,windows服务等)。无论出于何种原因,用户可能想要使用自己的日志记录工具......
另一方面,如果您只编写程序中使用的辅助函数,则变体1可以更方便: