0

在我的项目中,我需要将共享文件复制到一个名为 share 的目录中。我的想法是使用 fgets 和 fputs 复制此文件的包含:

FILE *fp;
int size;
char *fileBuff

fseek(fp,0,SEEK_END );
size=ftell(fp);
printf("Size of %s: %d bytes.\n",path,size); // print correct size 
fileBuff=malloc(size); // mallocate the file buffer
printf("\nsize of file buffer is %d",sizeof(fileBuff)); //always print 4!!
while(!feof(fp)){
    fgets(fileBuff,size,fp); // put into file buffer

}
printf("\nsize of file buffer is %d",sizeof(fileBuff)); // also print 4!!

但是,文件缓冲区不能被分配,这个文件缓冲区的大小总是4。发生了什么?

更新:似乎有一些误解。sizeof() 如果只是为了检查文件缓冲区中是否存储了任何东西。我确实尝试了 strlen(fileBuff),它总是给我 1。

4

5 回答 5

4

这是错误的:sizeof(fileBuff)。这将是指针的大小,在您的系统上为 4。

您不能使用sizeof“提取”返回的内存块的大小malloc()。您不能使用任何东西来提取该大小,这在(标准)C 中根本不可能。您需要使用该size值,即malloc().

此外,ftell()returns long、 notint和 bothmalloc()以及各种 I/O 调用都可能失败,您需要考虑到这一点。

在我看来,使用文件大小的缓冲区进行简单复制并不是一个好主意;最好使用“合理”的缓冲区(其确切的最佳大小取决于很多因素),然后在循环中重复读写对,直到您流式传输整个文件。

更新有关您的代码的更多要点:

  1. 您谈论使用strlen(),但代码也显示sizeof在 之后fread()
  2. 您谈论使用sizeof“检查”缓冲区中是否有任何东西,这是不可能的;任何带有 的表达式sizeof总是在编译时评估1,它不能用于检查这样的动态事物。而且,同样,您不能使用它来计算由malloc().
  3. strlen()仅当文件是二进制文件并且在其最后位置包含 '\0' 时,在保存文件数据的缓冲区上使用 才能可靠地工作,否则您将有一个未终止的字符串并strlen()可能调用未定义的行为。
  4. 正如我所说,您需要检查是否malloc()返回NULL,如果它未能分配请求的内存块,它将执行此操作。

1除了 C99 中的灵活数组,但让我们忽略它。

于 2012-04-13T09:18:00.507 回答
2

99 位开发人员现在将回答您正在获取指针的大小。我什至不必看代码。

于 2012-04-13T09:19:18.400 回答
0

除了对sizeof()的不当使用之外,您还可以考虑另外 2 个想法:

如果只是复制文件:不要试图重新发明轮子,只需使用system()函数并调用为此设计的操作系统程序(cp在 unix 上,在 DOS/Windows上复制)。

如果它是出于培训目的,因此您坚持自己做:不要尝试读取整个文件然后再次将其写出,而是逐块读取和写入。使用大缓冲区大小只会导致 CPU 缓存毫无价值。通常匹配文件系统缓冲区大小或它的一小部分是一个好的块大小,所以伪代码应该如下所示:

open input file for reading
open output file for writing
as long as read from input file BUFSIZE bytes and read bytes > 0
     do write read data to output file
close input file
close output file

(并且不要忘记在每次调用 I/O 例程后检查 I/O 错误!)

最后一点:除非您确定它始终是纯文本文件,否则不要使用fgets() 。如果您选择使用fread()/fwrite(),即使它是二进制文件(也更快),您也可以保存。

于 2012-04-13T10:05:00.413 回答
0

char *您(32 位)平台上的指针 ( ) 的大小始终为 4。

您无法sizeof确定为缓冲区分配了多少内存。

要检查指针是否已分配,请检查以下的返回值malloc()

fileBuff = malloc(size);

if (fileBuff == 0) {
   fprintf(stderr, "Error allocating %d bytes.\n", size);
   abort();
}
于 2012-04-13T09:18:12.057 回答
0

sizeof编译时进行评估,因为您要sizeoffilebufchar*编译器计算它是 4 个字节(因为指针的大小是 4 个字节 ub 您的平台)并打印它。你所做的malloc与你无关sizeof

于 2012-04-13T09:20:15.193 回答