fread为空(0kb)文件的行为

时间:2015-01-28 05:58:39

标签: c file fread

以下是在读取空文件时给出分段错误的示例代码。

#include <stdio.h>

main()
{
    FILE *fp;
    int i = 0;
    char buffer[20];

    printf("1\n");
    fp = fopen("/home/amadhab/aa", "r+");
    printf("2\n");
    i = fread(buffer, 1, 1, fp);
    printf("3\n");
    printf("i = %d\n", i);
}

将o / p视为

1
2
Segmentation fault

fread()无法读取空(0KB)文件吗?

4 个答案:

答案 0 :(得分:6)

如果程序有效,会发生什么:

1
2
3
i = 0

fread()失败时,返回0(或小于请求的项目数的数字)。但是,这不会发生。这可能是因为fp为空。您不能将null参数传递给fread()。可能fp为空,因为/home/amadhab/aa不存在。尝试使用它来代替打开文件:

#include <assert.h>

fp = fopen("/home/amadhab/aa", "r+");
assert(fp != NULL);

或者,有关更多信息,

#include <err.h>

const char *fname = "/home/amadhab/aa";
fp = fopen(fname, "r+");
if (!fp)
    err(1, "%s", fname)

请注意,err()函数是BSD扩展,但如果担心可移植性,则可以在其他系统上使用strerror()perror()

标准

从n1516第7.21.8.1节:

  

fread函数从ptr指向的数组中读取nmemb的大小由size指定的stream个元素。 {1}}。

请注意,NULL未指向流,因此通过传递NULL,您违反了fread()功能的前提条件。这在7.1.4节中明确说明:

  

如果[library]函数的参数具有无效值(例如[...]空指针[...])[...],则行为未定义。

答案 1 :(得分:1)

对于空文件,无法执行任何操作。 Source

正如其他人已经指出的那样,错误与函数本身无关。

答案 2 :(得分:1)

在您的代码中

fp = fopen("/home/amadhab/aa", "r+");

没有成功检查fopen()返回值。如果fopen()失败,它将返回NULL(在fp中收集)并且随后使用用于收集返回值的变量fp将导致{{3} } 注意。这就是

中发生的事情
fread(buffer, 1, 1, fp);  // note the usage of fp here

导致分段错误。

为避免这种情况,您应立即检查fopen()的返回值,如果失败,则应避免访问fp

注意:只是一个建议,学习使用调试器[如Linux上的gdb]并逐步完成您的应用程序。大多数情况下,它查明确切的问题。


注意:请参阅附件J,C99,作为未定义行为背后的原因,

  

库函数的参数具有无效值或具有可变参数数量的函数不期望的类型(7.1.4)。

并且,认为 无效值,FILE *将传递给fread()

答案 3 :(得分:1)

读取空文件时,Fread不会失败。你没有检查流开放 这是正确打开的。

fp = fopen("/home/amadhab/aa", "r+"); 

在这种情况下,如果该文件的打开失败。现在fp的值为NULL。

i = fread(buffer, 1, 1, fp);

现在您正在访问NULL文件流。这就是分段错误的原因。为了避免这种情况,你必须检查条件。

if ( ( fp = fopen("/home/amadhab/aa", "r+") ) == NULL  ){
            perror("fopen");
            exit(5);
}