2015-11-07 23 views
1

比方说,我有一个5000字节大小的文件,我试图读取它。在fread调用中元素的大小和数量是否可以交换?

我有这样的代码:

int main() 
{ 
    char *file_path[] = "/path/to/my/file" 
    FILE *fp= fopen(file_path,"rb"); //open the file 
    fseek(fp, 0, SEEK_END); // seek to end of file 
    unsigned long fullsize = ftell(fp); //get the file size (5000 for this example) 
    fseek(fp, 0, SEEK_SET); //bring back the stream to the begging 
    char *buf = (char*)malloc(5000); 
    fread(buf,5000,1,fp); 
    free(buf); 
    return 0; 
} 

我也可以代替fread呼叫与

fread(buf,1000,5,fp); 

什么是好?为什么? 在优化问题上,我了解到返回值是不同的。

+1

这两段代码做了不同的事情。你想达到什么目的? – Nayuki

+1

你的意思是'fread(buf,1000,5,fp)'和'fread(buf,5000,1,fp)'之间的区别吗? – Downvoter

+0

@cad是的。我试图在buf中处理数据,并操纵他..一些memcpy,一些写入另一个文件.. – raptor0102

回答

1

我总是发现它最好使用1的元素大小。如果fread() 无法读取文件末尾的完整元素,它将跳过 最后的部分元素。当最后一个元素为 时,这是不可取的。另一方面,使用1作为元素大小没有任何危害。

,打印本身并演示了这种行为

示例代码:

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

#define SIZE 100 
#define N 1 

int main() 
{ 
    FILE *fin; 
    int ct; 
    char buf[SIZE * N + 1]; 

    fin = fopen("size_n.c", "r"); 

    while (1) { 
     ct = fread(buf, SIZE, N, fin); 
     if (!ct) 
      break; 
     buf[ct * SIZE] = '\0'; 
     fputs(buf, stdout); 
    } 
} 
+0

在这个例子中 - 因为你正在阅读'char's - 实际上*的元素大小是* 1。但是如果你正在阅读,比方说'double'的数组,不读“最后的部分元素”可能是合适的。 – 5gon12eder

+0

@ 5gon12eder:恩,是的,我想你是对的。但是,由于可移植性,我一直非常努力地拒绝阅读这样的机器专用格式。 –

+0

是的,这通常是一个好主意,但我认为'fread'函数接受size参数的原因是读取'char's以外的类型。这样做并不总是坏事。例如,如果在同一台机器上运行两个进程,通过管道进行通信,则使用二进制格式非常合适。 – 5gon12eder

1

如果你交换这两个参数,你仍然要求读取相同的字节数。然而行为在其他方面是不同的:

  • 既然你应该总是被检查fread返回值如果文件大于量
  • 返回值

短,会发生什么,这很重要:)

如果使用的形式为result = fread(buf, 1, 5000, fp);,即读取5000单元的大小为1,但是fi文件大小只有3000,那么会发生什么是那些3000字节被放置在您的缓冲区中,并返回3000

换句话说,你可以检测部分读取并仍然使用部分结果。如果使用result = fread(buf, 5000, 1, fp);

然而,即读1单元尺寸5000的,则缓冲器的内容是不定(即相同的未初始化的变量的状态),并且返回值是0

在这两种情况下,部分读取离开处于不确定状态的文件指针,即你需要fseek做任何进一步读取之前。

使用后一种形式(即除1以外的任何大小)可能最适合当您要中止全尺寸不可用或者正在读取具有固定大小记录的文件时。

相关问题