用于跟踪错误发生位置的常用C语言

时间:2011-11-19 21:04:09

标签: c error-handling

我有一项任务,我需要从文件中读取一定数量的Foo s。如果文件中的数据对于Foo之一的格式不正确,那么有哪些常见的方式(例如stderr)确切地发出Foo s的信号。应该纠正吗?

我的代码看起来像这样:

Foo foos[50];
FILE *file = fopen(...);
int i;

for (i = 0; i < sizeof(foos); ++i)
{
    if (readFoo(&foos[i], file) != 1)
        break;
} 

如果读取成功,readFoo函数将返回1;如果没有,它将返回一个负数并向stderr输出一个错误,指出错误但未说明错误的位置。我应该如何实现这个( cleanely ),以便我也告诉用户i的值?

在C ++中我会用异常来做这件事。在C中我想做这样的事情(readFoo会在事情不正确时相应地设置error

/* These go in a source file */
const char *error = NULL;
const char error1[] = "Error 1 occurred.";
const char error2[] = "Error 2 occurred."; 

const char *getLastError() {
    return error;
}

还有其他方法可以解决这个问题吗?

3 个答案:

答案 0 :(得分:2)

类Unix操作系统中的一个众所周知的习惯是errno(3),其中系统调用将在出错时返回-1并设置全局变量以指定特定的错误类型。由于这对多线程不能很好地发挥作用,因此最初的想法被颠覆为errno被定义为对检索每线程错误代码的函数的调用。

然后,POSIX threads API以另一种方式在成功时返回零,并在失败时返回错误代码。在我看来,这是用户 - 土地代码错误报告的首选方式,我建议遵循这一点。

答案 1 :(得分:2)

执行此操作的“干净”方法是在呼叫站点执行错误报告。也就是说,做一些事情:

if( readFoo( foos + i, file, errbuf, errbuf_size ) != 1 ) {
    fprintf( stderr, "%d: %s\n", i, errbuf );
    ...    
}

也就是说,让readFoo使用错误消息填充缓冲区,而不是将其写入stderr。

答案 2 :(得分:1)

标准C提供errno来区分错误。如果您愿意,也可以这样做。看起来你已经有了一个循环并且知道i是什么。你不能这样做:

if (readFoo(&foos[i], file) != 1) {
    fprintf(stderr, "Read error on foo #%d\n", i);
    break;
}