简体   繁体   English

为什么 ftell 在这个函数中返回 0?

[英]Why the ftell returns 0 in this function?

When I run my program and I choose to see the product list, it doesn't print anything.当我运行我的程序并选择查看产品列表时,它不会打印任何内容。 After some time, I find out that the value of fl_size is always 0. Why is this?过了一段时间,发现fl_size的值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);
}

ftell does not return the total size of the file; ftell不返回文件的总大小; it returns the current read or write position within the file.它返回文件中的当前读取或写入位置 You call ftell immediately after opening the file, so that position is the very beginning of the file.打开文件后立即调用ftell ,因此该位置是文件的开头。 You can either use fseek(stock, 0, SEEK_END) to seek to the end before calling ftell , or you can drop down a layer and use fstat(fileno(stock)) to retrieve the file size directly from the OS.您可以在调用ftell之前使用fseek(stock, 0, SEEK_END)寻找到最后,或者您可以下拉一个层并使用fstat(fileno(stock))直接从操作系统检索文件大小。

Further notes:补充说明:

  1. Neither of these options will work if you are reading from a pipe.如果您从管道中读取,这些选项都不起作用。 (In general, you need to check for the success of every single one of your file access operations.) (通常,您需要检查每个文件访问操作是否成功。)
  2. fread is not guaranteed to read the entire file in one gulp even if you ask it to.即使您要求fread也不能保证fread读取整个文件。
  3. As 'alk' points out, ftell returns a long , not an int .正如 'alk' 指出的那样, ftell返回一个long ,而不是一个int
  4. If long is only 32 bits, it is possible for a file to be so large that its size does not fit in a long .如果long只有 32 位,则文件可能太大以至于它的大小无法放入long If your program needs to handle files that big, you need to #define _FILE_OFFSET_BITS 64 at the top of every .c file (before all the includes) and use fseeko and ftello .如果您的程序需要处理那么大的文件,您需要在每个.c文件的顶部(在所有包含之前) #define _FILE_OFFSET_BITS 64并使用fseekoftello (Or whatever the Windows equivalent is.) (或任何 Windows 等价物。)
  5. You should be opening this apparently-binary file with mode "r+b" .您应该使用"r+b"模式打开这个明显的二进制文件。
  6. Binary files with no file header (and in particular with no magic number , of at least four bytes, at offset zero) are a Bad Thing.没有文件头的二进制文件(特别是没有幻数,至少四个字节,偏移量为零)是一件坏事。
  7. Do not cast the return value of malloc .不要malloc的返回值。 (It is necessary to do this in C++, but in C it is not only unnecessary, it can hide bugs .) (在 C++ 中必须这样做,但在 C 中它不仅没有必要,而且可以隐藏错误。)

Check man page for ftell , for example this one: http://linux.die.net/man/3/ftell检查ftell手册页,例如这个: http : //linux.die.net/man/3/ftell

Here is the relevant part: "The ftell() function obtains the current value of the file position indicator for the stream pointed to by stream."这是相关部分: “ftell() 函数获取流指向的流的文件位置指示符的当前值。”

When you open the file, cursor position will be at the start.当您打开文件时,光标位置将在开头。 So distance from start will be zero.所以与开始的距离将为零。 Therefore ftell returns zero.因此ftell返回零。

To find the size of file, see this link: How can I get a file's size in C?要查找文件的大小,请参阅此链接: How can I get a file's size in C? . . Here's a snippet in short:这是一个简短的片段:

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

Make sure to call fseek(fp, 0L, SEEK_SET);确保调用fseek(fp, 0L, SEEK_SET); after above.以上之后。

Because ftell returns the size from the beginning to the current position of the file.因为ftell返回的是文件从开始到当前位置的大小。

fseek(stock,0,SEEK_SET);

Means you set the position to the first bite of the file.意味着您将位置设置为文件的第一口。

Also you gotta set fl_size=ftell(stock);你还必须设置fl_size=ftell(stock); after the fseek .fseek

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM