1

当我运行我的程序并选择查看产品列表时,它不会打印任何内容。一段时间后,我发现 的值fl_size始终为 0。这是为什么呢?

void view_prdct_code_list() {
        FILE *stock = fopen("stock.dat","r+");
        assert(stock);

        int fl_size=ftell(stock);
        int prd_size= sizeof(product);
        int quantity= fl_size/prd_size;
        printf("fl_size=%d",fl_size);

        fseek(stock,0,SEEK_SET);
        prdct cprd= (product *)malloc (sizeof(product)*quantity);
        assert(cprd);

        int i;

        fread(cprd,prd_size,quantity,stock);

        for (i=0;i<quantity;i++){
                printf("PRODUCT CODE: %d\n",cprd->code);
        }

        free(cprd);
        fclose(stock);
}
4

3 回答 3

8

ftell不返回文件的总大小;它返回文件中当前的读取或写入位置。您ftell在打开文件后立即调用,因此该位置是文件的开头。您可以fseek(stock, 0, SEEK_END)在调用 之前使用 搜索到结尾ftell,也可以下拉一层并使用fstat(fileno(stock))直接从操作系统检索文件大小。

进一步说明:

  1. 如果您从管道中读取,这些选项都不起作用。(通常,您需要检查每一个文件访问操作是否成功。)
  2. fread即使您要求,也不能保证一口气读完整个文件。
  3. 正如“alk”指出的那样,ftell返回 a long,而不是 a int
  4. 如果long只有 32 位,则文件可能太大以至于它的大小不适合long. 如果您的程序需要处理那么大的文件,您需要#define _FILE_OFFSET_BITS 64在每个文件的顶部.c(在所有包含之前)并使用fseekoand ftello。(或任何 Windows 等价物。)
  5. 您应该使用 mode 打开这个明显的二进制文件"r+b"
  6. 没有文件头的二进制文件(特别是没有幻数,至少四个字节,偏移量为零)是一件坏事。
  7. 不要强制转换的返回值malloc。(在 C++ 中这样做是必要的,但在 C 中不仅没有必要,它还可以隐藏错误。)
于 2014-06-03T16:01:49.587 回答
2

检查手册页ftell,例如这个: http: //linux.die.net/man/3/ftell

以下是相关部分:“ftell() 函数获取流指向的流的文件位置指示符的当前值。”

打开文件时,光标位置将位于开头。因此,与开始的距离将为零。因此ftell返回零。

要查找文件的大小,请参阅此链接:如何在 C 中获取文件的大小?. 这是一个简短的片段:

fseek(fp, 0L, SEEK_END);
sz = ftell(fp);

确保fseek(fp, 0L, SEEK_SET);在上面调用。

于 2014-06-03T16:01:21.217 回答
0

因为ftell返回文件从开头到当前位置的大小。

fseek(stock,0,SEEK_SET);

意味着您将位置设置为文件的第一口。

你也必须fl_size=ftell(stock); .fseek

于 2014-06-03T15:56:33.677 回答