在C中的错误处理和SO上的几个答案的所有示例中,所有程序都只退出状态代码。我不是在寻找任何一种。
错误是输入和输出的一部分,例程可以返回结果或错误。我希望函数返回错误的正确详细信息而不是异常退出或成功的结果。
以下不是可行的,但我正在寻找类似的东西,以指示函数返回的结果或错误。
struct Error {
int code;
char *message;
};
int div(int x, int y) {
if( y == 0){
struct Error *error = {0, "Division by zero!"};
return error;
} else {
return x / y;
}
}
int main() {
printf("%d", div(4, 2));
printf("%d", div(4, 0));
}
答案 0 :(得分:4)
findViewById(R.id.button).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
int red= new Random().nextInt(255);
int green= new Random().nextInt(255);
int blue= new Random().nextInt(255);
ThemeColors.setNewThemeColor(MainActivity.this, red, green, blue);
}
});
- > struct Error *error =
,然后返回struct Error error =
类型。
但是因为你有一个结构,按值返回通常不是一个好主意。此外,数学函数的返回值很可能是数学结果。因此,比返回错误更好的方法是使用可选参数:
struct Error
答案 1 :(得分:1)
对于它的所有缺陷,Zed Shaw以艰难的方式学习C'有一个很好的部分" C错误处理问题"你可能会感兴趣。
我认为解决这个问题的一种方法是使用调试宏来包装全局的“错误”。 C提供的价值。
以下' dbg.h'代码取自Zed Shaw的书:
dbg.h:
#ifndef __dbg_h__
#define __dbg_h__
#include <stdio.h>
#include <errno.h>
#include <string.h>
#ifdef NDEBUG
#define debug(M, ...)
#else
#define debug(M, ...) fprintf(stderr, "DEBUG %s:%d: " M "\n",\
__FILE__, __LINE__, ##__VA_ARGS__)
#endif
#define clean_errno() (errno == 0 ? "None" : strerror(errno))
#define log_err(M, ...) fprintf(stderr,\
"[ERROR] (%s:%d: errno: %s) " M "\n", __FILE__, __LINE__,\
clean_errno(), ##__VA_ARGS__)
#define log_warn(M, ...) fprintf(stderr,\
"[WARN] (%s:%d: errno: %s) " M "\n",\
__FILE__, __LINE__, clean_errno(), ##__VA_ARGS__)
#define log_info(M, ...) fprintf(stderr, "[INFO] (%s:%d) " M "\n",\
__FILE__, __LINE__, ##__VA_ARGS__)
#define check(A, M, ...) if(!(A)) {\
log_err(M, ##__VA_ARGS__); errno=0; goto error; }
#define sentinel(M, ...) { log_err(M, ##__VA_ARGS__);\
errno=0; goto error; }
#define check_mem(A) check((A), "Out of memory.")
#define check_debug(A, M, ...) if(!(A)) { debug(M, ##__VA_ARGS__);\
errno=0; goto error; }
#endif
在您要检查的代码中,您可以执行以下操作:
#include <stdio.h>
#include "dbg.h"
int div(int x, int y) {
check ( y != 0, "Division by zero!");
return x / y;
error:
log_err("Div by zero error.");
return 0;
}
int main() {
printf("%d", div(4, 2));
printf("%d", div(4, 0));
}
这样你的错误就会被“dbg.h&#39;”中的代码捕获和处理。 现在这有一个明显的问题,当调用div(x,0)时:div返回0.问题是div()必须返回一个int,并且所有的int都可以由div(x,y)的某个有效组合产生对于整数x和y。
一种解决方案是将div包装在另一个函数中:
#include <stdio.h>
#include <stdlib.h>
#include "dbg.h"
char *div_interface(int x, int y) {
check ( y != 0, "Division by zero!");
char *buffer = malloc(100);
sprintf(buffer, "%d", (x / y));
return buffer;
error:
log_err("Div by zero error.");
char *err_ret= strdup("Div by zero error.");
return err_ret;
}
int main() {
char *div_1 = div_interface(4, 2);
printf("%s\n", div_1);
free(div_1);
char *div_2 = div_interface(4, 0);
printf("%s\n", div_2);
free(div_2);
}
尽管如此,这并不是特别优雅!然后调用者必须从char *转换为int ...
答案 2 :(得分:0)
当函数返回int时,不能返回结构。但是你可以返回不同的整数然后处理它。
#include <stdio.h>
#include <stdlib.h>
typedef enum
{
ERR_NONE,
ERR_DIV_BY_ZERO
} err_code_t;
typedef struct
{
err_code_t code;
const char *message;
} err_t;
int division (int x, int y, err_t* err)
{
int result;
if( y == 0)
{
if(err != NULL)
{
err->code = ERR_DIV_BY_ZERO;
err->message = "Division by zero";
}
result = 0;
}
else
{
result = x / y;
}
return result;
}
void error_handler (const err_t* err)
{
fprintf(stderr, "Error %d: %s", err->code, err->message);
exit(EXIT_FAILURE);
}
int main()
{
err_t err;
int result;
result = division(4, 2, NULL); // NULL meaning don't give any error information
printf("%d\n", result);
result = division(4, 0, &err);
if(err.code != ERR_NONE)
{
error_handler(&err);
}
printf("%d\n", result);
}
我知道有时结果可能小于零,但它只是一个粗略的例子。