故意返回无效值或类型
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了故意返回无效值或类型相关的知识,希望对你有一定的参考价值。
作为Stephen Kochan的“Programming in C”(第3版)的建议练习,我想在strToInt
函数中添加一些功能,将字符串转换为整数。该函数有一个返回类型int
,如果传递的字符串文字有效(如“123”或“13”),这是很好的。但是如果字符串包含任何非数字值(例如“12x3”,“foo”),则应打印错误消息并退出该函数。由于返回类型是int
,因此需要返回一个整数,但在这种情况下,这可能会产生误导。所以我的问题是,在这种情况下应该返回什么,以便返回的值/类型明确地说明了一个无效的字符串文字已被传递并且不能与有效的返回值混淆?
int strToInt(const char string[])
{
int i = 0, intValue, result = 0;
// check whether string passed is a valid literal
while (string[i] != ' ')
{
if (string[i] < '0' || string[i] > '9')
{
printf("ValueError: Invalid literal
");
return; // what should be returned here?
}
++i;
}
for (i = 0; string[i] >= '0' && string[i] <= '9'; ++i)
{
intValue = string[i] - '0';
result = result * 10 + intValue;
}
return result;
}
//这里应该归还什么?
没有什么可以回到这里看起来不是一个有效的结果。通常解决的方法是将结果移动到输出参数。从而释放指示操作成功的状态的返回值。例如:
#include <stdbool.h>
bool strToInt(const char string[], int* outInt) {
// check whether string passed is a valid literal
while (string[i] != ' ')
{
if (string[i] < '0' || string[i] > '9')
{
printf("ValueError: Invalid literal
");
return false;
}
}
int result = 0;
for (int i = 0; string[i] >= '0' && string[i] <= '9'; ++i)
{
intValue = string[i] - '0';
result = result * 10 + intValue;
}
if (outInt) // Or you may move the check earlier and return false too
*outInt = result;
return true;
}
您当然可以返回任何类型而不仅仅是bool。许多软件系统返回几个整数值中的一个,这些值可以指示操作可能失败的几种方式中的任何一种因此,错误处理可以更精确和复杂。
这是软件工程中一个有趣的问题,并没有“最佳答案”。
在某些情况下,分配范围的特定值可能有效。例如,在标准C库中,某些字符操作函数(如getc
)的返回类型设置为int而不是char。这是为了能够返回-1作为错误代码。
其他函数,例如strtod
,如果没有可能从字符串转换为double,则返回0(这可以被认为是否是好的方法)。如果发生错误,它们会返回一个特殊值(仍然是一个有效的双精度值)并设置errno
,
Errno似乎是unix世界中错误报告的标准方法。在核心,它基本上是一个全局变量,存储最后一个错误的错误代码。当发生某些事情时,大多数系统调用返回一个特定的值,然后你应该检查errno中的错误代码,看看发生了什么。
那么做strto*
函数做什么 - 它们返回转换后的数字(如果有的话),然后将指针重置为它无法辨认的部分的开头。使用同样的音调可以做很多事情 - 如果你通过standard,你可以清楚地了解它。
因此,在给定12x3
示例的情况下,您的函数可能返回12
,然后使指针指向字符串中的适当位置。这是通过传递的指针提供错误信息,然后返回尽可能多的从输入解析。
对于来自strtol
页面的[long int strtol(const char *nptr, char **endptr, int base);]
(man
),我们可以看到当endptr
设置为字符串的末尾时,这意味着整个字符串我成功解析。在部分转换的情况下,endptr
不会指向字符串的中间。同样地模仿strto*
函数我们可以看到它将errno
设置为适当的数字来表示不同的问题(ERANGE
等) - 所以你可以设置它以给用户一个精确的错误报告。
以上是关于故意返回无效值或类型的主要内容,如果未能解决你的问题,请参考以下文章