如何在fgets()中有意触发错误?

3

概述

在使用fgets()时,我有一些错误检查代码,在fgets()返回null但未到文件结尾时执行一些纠正操作。我想测试这段代码,以验证它是否按预期工作。

是否有一种标准方法来触发fgets()失败?无论是通过手动手段(在调用fgets()之间某种方式删除文件),还是通过一些测试设置(提供一个已知的“损坏”文件),或者其他一些方式?


最小可重现示例

fgets_fail_test.cpp:

// Test code to show minimally reproducible example of fgets() error handling
// The desire is to manually trigger a failure in fgets()

#include <errno.h>
#include <iostream>
#include <stdio.h>
#include <string.h>

int main(int argc, char **argv) {
    FILE *fp = fopen("test_file.txt", "r"); //assume this works, not testing this
    char buf[100]; //assume large enough to hold data
    unsigned int lineno = 1;

    while (fgets(buf, 100, fp)) {
        std::cout << buf;
        lineno++;
    }

    if (feof(fp)) {
        std::cout << "End of file encountered.\n";
    }
    else if (ferror(fp)) { // how do I trigger an fgets error to cause this to return true?
        printf("Encountered read error at line no %u. Error: %d, %s.\n",
               lineno,
               errno,
               strerror(errno));
    }

    fclose(fp); // assume this works, not testing this

    return 0;
}

test_file.txt:

ABCDEFG
HIJKLMN
OPQRSTU
VWXYZ
The quick brown fox
jumped over the
lazy dog.
Goodbye.

理论

虽然我可以用一些测试脚手架来替换问题中的代码(编写一个保持内部状态的fgets包装器,增加计数器,当它达到第N行时返回null并手动设置文件错误和errno),但我觉得应该有一种“内置”的方法来实现这一点?

如果唯一的解决方案是搭建脚手架,那我就这样做。说实话,也许我在这里想得太聪明了。


1
你必须使用C文件处理吗?如果你正在使用C++,你可以使用C++文件流,它们允许你设置和清除错误位。 - NathanOliver
1
由于您在“文本模式”下打开,那么文件中的特殊字符怎么办?我所说的特殊字符是指(int)charater < 32 - Ripi2
2
如果您使用的是Linux系统,您可以使用其中之一 - Artyer
1
你可以尝试在循环中执行操作,并在操作过程中分离设备。 - eerorika
1
@John 我在考虑实际的硬件。我怀疑卸载或其他虚拟操作可能会处理得太好了,但一些强制选项可能有效。 - eerorika
显示剩余5条评论
1个回答

1
很多相关的问题都有很好的答案,这可能会使我的问题成为重复问题。尽管我最初搜索时专注于fgets(),但我找不到这些答案。一些相关的问题包括: 因为我的程序从已知文件列表中读取数据,并具有给定的文件名格式,所以我需要使用一种方法,允许我向程序提供一个有故障的文件(而无需修改代码)。我决定使用这个答案来做到这一点。

方法

为了生成一个有故障的文件,触发fgets()的读取失败,我利用了/ proc / self / mem的“功能”,从中读取会导致I/O错误。

我删除了旧的输入文件,并在旧名称下链接了一个新文件到/proc/self/mem

ln -s /proc/self/mem test_file.txt

运行该文件后,会生成以下输出:
Encountered read error at line no 1. Error: 5, Input/output error.

提示我们触发了错误。感谢 @Artyer 的评论,他们最初将我链接到相关的问题。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接