我在C中编写了一个函数,它将字符串转换为整数并返回整数.当我调用该函数时,我也希望它告诉我字符串是不是有效数字.在过去,当发生此错误时,我返回-1,因为我不需要将字符串转换为负数.但现在我希望它将字符串转换为负数,那么报告错误的最佳方法是什么?
如果我不清楚这一点:我不希望此函数向用户报告错误,我希望它将错误报告给调用该函数的代码.("报告"可能是错误的用词...)
这是代码:
s32 intval(const char *string) {
bool negative = false;
u32 current_char = 0;
if (string[0] == '-') {
negative = true;
current_char = 1;
}
s32 num = 0;
while (string[current_char]) {
if (string[current_char] < '0' || string[current_char] > '9') {
// Return an error here.. but how?
}
num *= 10;
num += string[current_char] - '0';
current_char++;
}
if (negative) {
num = -num;
}
return num;
}
Run Code Online (Sandbox Code Playgroud)
Mic*_*urr 35
有几种方法.所有人都有他们的优点和缺点.
让函数返回错误代码并传入指向某个位置的指针以返回结果.关于这一点的好处是没有结果的重载.不好的是你不能直接在表达式中使用函数的实际结果.
Evan Teran提出了一个变体,它使调用者传递一个指向成功变量的指针(如果调用者不关心,可以选择为NULL)并返回函数的实际值.这样做的好处是,当调用者在错误结果中使用默认值或者知道函数不能失败时,允许函数直接在表达式中使用.
使用特殊的"sentinel"返回值来指示错误,例如负数(如果正常返回值不能为负数),INT_MAX或者INT_MIN如果良好值不能达到极值.有时为了获得更详细的错误信息,需要查询另一个函数(例如GetLastError())或全局变量(例如errno).如果您的返回值没有无效值,并且一般被许多人视为不良格式,则此方法无效.
使用此技术的示例函数是getc(),如果到达文件末尾或遇到错误,则返回EOF.
让函数永远不会直接返回错误指示,但要求调用者查询另一个函数或全局函数.这类似于VB的" On Error Goto Next"模式的工作原理 - 它几乎被普遍认为是一种糟糕的方式.
另一种方法是拥有"默认"值.例如,atoi()函数与函数intval()几乎完全相同,当它无法转换任何字符时将返回0(它与函数的不同之处在于它消耗字符进行转换,直到它到达字符串的末尾或者不是数字的字符).
这里明显的缺点是,判断实际值是否已转换或是否已传递垃圾可能很棘手atoi().
我不是这种处理错误的忠实粉丝.
我会更新,因为其他选项在我脑海中浮现......
Jon*_*eet 16
那么,.NET在Int32.TryParse中处理它的方式是返回成功/失败,并使用pass-by-reference参数传回解析后的值.同样可以在C中应用:
int intval(const char *string, s32 *parsed)
{
*parsed = 0; // So that if we return an error, the value is well-defined
// Normal code, returning error codes if necessary
// ...
*parsed = num;
return SUCCESS; // Or whatever
}
Run Code Online (Sandbox Code Playgroud)
Eva*_*ran 11
一种常见的方法是将指针传递给成功标志,如下所示:
int my_function(int *ok) {
/* whatever */
if(ok) {
*ok = success;
}
return ret_val;
}
Run Code Online (Sandbox Code Playgroud)
这样叫:
int ok;
int ret = my_function(&ok);
if(ok) {
/* use ret safely here */
}
Run Code Online (Sandbox Code Playgroud)
编辑:这里的示例实现:
s32 intval(const char *string, int *ok) {
bool negative = false;
u32 current_char = 0;
if (string[0] == '-') {
negative = true;
current_char = 1;
}
s32 num = 0;
while (string[current_char]) {
if (string[current_char] < '0' || string[current_char] > '9') {
// Return an error here.. but how?
if(ok) { *ok = 0; }
}
num *= 10;
num += string[current_char] - '0';
current_char++;
}
if (negative) {
num = -num;
}
if(ok) { *ok = 1; }
return num;
}
int ok;
s32 val = intval("123a", &ok);
if(ok) {
printf("conversion successful\n");
}
Run Code Online (Sandbox Code Playgroud)