如何处理C语言中的错误?
比如,我有这样的代码:如何处理C语言中的错误?,c,error-handling,C,Error Handling,比如,我有这样的代码: int foo() { ... int buff_size; scanf("%d", &buff_size); FILE * fp = fopen("./file", "a+"); char *buff = malloc(buff_size*sizeof(char)); char *buff2 = malloc(buff_size*sizeof(char)); char *buff3 = malloc(buf
int foo() {
...
int buff_size;
scanf("%d", &buff_size);
FILE * fp = fopen("./file", "a+");
char *buff = malloc(buff_size*sizeof(char));
char *buff2 = malloc(buff_size*sizeof(char));
char *buff3 = malloc(buff_size*sizeof(char));
while (!feof(fp)) {
/*do something, say read, write etc.*/
if (/*error case 1*/) {
free(buff);
free(buff1);
free(buff3);
fclose(fp);
return -1;
}
else if (/*error case 2*/) {
free(buff);
free(buff1);
free(buff3);
fclose(fp);
return -2;
}
...
else if (/*error case k*/) {
free(buff);
free(buff1);
free(buff3);
fclose(fp);
return -k;
}
}
...
free(buff);
free(buff1);
free(buff2);
fclose(fp);
return 0;
}
因为C不提供try…throw…finally语法,所以在返回错误整数代码之前,我必须关闭我创建的文件描述符和释放堆内存指针。它会产生一些重复的代码,使代码变得丑陋
有人知道我应该如何修改这类代码以使其看起来更简洁吗?对于这类常见的清理代码,我会使用一个返回值变量和一个
goto
:
int foo() {
...
// append extended mode ... what are you doing with this?
FILE * fp = fopen("./file", "a+");
char buff[1024];
char buff2[1024];
char buff3[1024];
int ret = 0;
while (/* file I/O is valid on fp */) {
/*do something, say read, write etc.*/
if (/*error case 1*/) {
ret = -1;
goto cleanup;
}
else if (/*error case 2*/) {
ret = -2;
goto cleanup;
}
...
else if (/*error case k*/) {
ret = -k;
goto cleanup;
}
}
...
cleanup:
free(buff);
free(buff2);
free(buff3);
fclose(fp);
return ret;
}
这还可以防止复制粘贴代码,或重新键入有错误的代码(正如您当前的代码一样)。对于常见的清理代码,我将使用一个返回值变量和一个
goto
:
int foo() {
...
// append extended mode ... what are you doing with this?
FILE * fp = fopen("./file", "a+");
char buff[1024];
char buff2[1024];
char buff3[1024];
int ret = 0;
while (/* file I/O is valid on fp */) {
/*do something, say read, write etc.*/
if (/*error case 1*/) {
ret = -1;
goto cleanup;
}
else if (/*error case 2*/) {
ret = -2;
goto cleanup;
}
...
else if (/*error case k*/) {
ret = -k;
goto cleanup;
}
}
...
cleanup:
free(buff);
free(buff2);
free(buff3);
fclose(fp);
return ret;
}
这还可以防止复制粘贴代码或重新键入有错误的代码(正如您当前的代码一样)。您编写的代码相当于
FILE * fp = fopen("./file", "a+");
int return_value = 0; /* assume zero means no error */
char *buff = malloc(1024*sizeof(char));
char *buff2 = malloc(1024*sizeof(char));
char *buff3 = malloc(1024*sizeof(char));
while (feof(fp))
{
/*do something, say read, write etc.*/
if (/*error case 1*/)
{
return_value = -1;
}
else if (/*error case 2*/)
{
return_value = -2;
}
// ...
else if (/*error case k*/)
{
return_value = -k;
}
}
if (return_value == 0) /* if no error has occurred, we can still do stuff */
{
...
}
/* I have assumed all buffers need to be released
and files closed as the function returns
*/
free(buff);
free(buff1); /* you probably intend buff2 and buff3 here, to match the malloc() calls */
free(buff2);
fclose(fp);
return return_value;
}
然而,我还没有解决代码中的两个关键错误。你需要这样做
可能会失败,并返回fopen()
。如果是,则将其传递给NULL
或feof()
将给出未定义的行为。您的代码根本没有检查这一点,需要在调用fclose()
和feof()
之前检查这两个属性fclose()
- 当(!feof(fp)){read_something_from(fp);use_something();}时,使用
形式的循环是个坏主意。查看以获取更多信息
不太重要-对于固定大小的数组(编译时大小固定),您可能不需要使用
malloc()
,这也意味着您不需要使用free()
。但是,您仍然需要处理fopen()
的潜在故障,因为编写的代码相当于
FILE * fp = fopen("./file", "a+");
int return_value = 0; /* assume zero means no error */
char *buff = malloc(1024*sizeof(char));
char *buff2 = malloc(1024*sizeof(char));
char *buff3 = malloc(1024*sizeof(char));
while (feof(fp))
{
/*do something, say read, write etc.*/
if (/*error case 1*/)
{
return_value = -1;
}
else if (/*error case 2*/)
{
return_value = -2;
}
// ...
else if (/*error case k*/)
{
return_value = -k;
}
}
if (return_value == 0) /* if no error has occurred, we can still do stuff */
{
...
}
/* I have assumed all buffers need to be released
and files closed as the function returns
*/
free(buff);
free(buff1); /* you probably intend buff2 and buff3 here, to match the malloc() calls */
free(buff2);
fclose(fp);
return return_value;
}
然而,我还没有解决代码中的两个关键错误。你需要这样做
可能会失败,并返回fopen()
。如果是,则将其传递给NULL
或feof()
将给出未定义的行为。您的代码根本没有检查这一点,需要在调用fclose()
和feof()
之前检查这两个属性fclose()
- 当(!feof(fp)){read_something_from(fp);use_something();}时,使用
形式的循环是个坏主意。查看以获取更多信息
不太重要-对于固定大小的数组(编译时大小固定),您可能不需要使用
malloc()
,这也意味着您不需要使用free()
。但是,您仍然需要处理fopen()
的潜在故障。如果您总是分配相同的固定大小,为什么不使用数组?也请阅读为什么你把这个标记为C++?<代码> siZoof(char)< /C>总是1。<代码> C++ +<代码>标签应该从这个问题中删除。因为,在c++
中的答案将不同于c
中的答案。关于c中“try-catch”的讨论很好:如果总是分配相同的固定大小,为什么不使用数组呢?也请阅读为什么你把这个标记为C++?<代码> siZoof(char)< /C>总是1。<代码> C++ +<代码>标签应该从这个问题中删除。因为,在c++
中的答案将不同于c
中的答案。关于c中“try catch”的良好讨论:请阅读上面关于feof
在中使用的注释,而looksEdited。现在OP应该选择他们的“is valid”表达式。使用goto()
是一个可怕的想法。结果是“意大利面条”代码。最好编写一个“sub”函数来处理清理,并将所需的任何参数值传递给它。请阅读上面关于while
looksEdited中使用feof
的注释。现在OP应该选择他们的“is valid”表达式。使用goto()
是一个可怕的想法。结果是“意大利面条”代码。最好编写一个“sub”函数来处理清理并向其传递所需的任何参数值。如果出现任何错误,是否应该保留while
-循环?@alk-我不建议避免while
循环。我说while(!feof())
(特别是)是个坏主意。如果出现任何错误,不应该保留while
-循环吗?@alk-我不建议避免while
循环。我说,,而(!feof())
(具体地说)是个坏主意。