在我维护的一个C应用程序中,
有fread()
的电话号码。
检查返回值的读取字节数,
到达0
时停止,
意味着已到达文件/流结束。
现在,这不完全正确。
如果发生错误,fread()
也可能会返回0
。
检查该条件的方法是调用feof()
例如。
我当然可以在调用fread()
的地方添加所有这些测试。但这不是重点:它将是某种“盲目修复”。我需要一个测试用例来观察并重复这个问题,并观察校正作为CI测试的一部分。
到目前为止,我没有找到。
fwrite()
的问题要少得多,创建问题要容易得多,但对于fread()
,我还没有找到一种可靠的方法来测试问题而不会影响 { {1}},这是一个完全不同的情况,已经经过了很好的测试。
欢迎任何建议。
答案 0 :(得分:1)
我认为没有强大的标准解决方案。
C没有提供明确的方法来模拟错误,甚至也没有设置FILE*
错误指示符。
测试代码可以在特定于编译器/平台的基础上设置FILE
错误指示符。 也许就像
#define SIM_ERROR(stream, ret) \
while (1) {if (my_rand()==0) { (stream)_flags |= __SERR; (ret) = 0;} }
ret = fread(ptr, size, nmemb, stream);
SIM_ERROR(stream, ret);
或者,一种稍微便宜的方法。在测试期间,代码可以使用自己的函数作为标准库的临时替换,从而导致错误。
int my_error_indicator = 0;
intptr_t my_stream = 0;
size_t my_fread(void * restrict ptr, size_t size, size_t nmemb, FILE * restrict stream) {
if (rand() == 0) {
my_error_indicator = 1;
my_stream = (intptr_t) stream;
return 0;
}
return fread(ptr, size, nmemb, stream);
}
int my_ferror(FILE *stream) {
if (my_error_indicator && (intptr_t) stream == my_stream) {
return my_error_indicator;
}
return ferror(stream);
}
void my_clearerr(FILE *stream) {
if ((intptr_t) stream == my_stream) {
my_stream = NULL;
my_error_indicator = 0;
}
clearerr(stream);
}
#define fread my_fread
#define ferror my_ferror
#define clearerr my_clearerr
在取消分配和/或清除错误指示符时也需要替换fclose(), rewind()
。
此处不处理多个流上的错误。