代码之家  ›  专栏  ›  技术社区  ›  Joshua Yonathan

<io.h>\u filelength和\u filelengthi64始终返回0

  •  0
  • Joshua Yonathan  · 技术社区  · 6 年前

    我使用低级io函数获取文件的大小(以字节为单位),并将其写入标准输出。我使用的是64位windows 7,我使用的是visual studio 2017 x64调试模式。函数\u filelength和\u filelengthi64是windows操作系统独有的,但是当我使用它们时,它们对于我打开的任何文件都返回0。这里是完整的代码,但问题应该只在于 _sopen_s() _filelengthi64()

    收割台

    #pragma once
    
    // Headers
    #include <io.h>
    #include <string.h>
    #include <sys\stat.h>
    #include <share.h>
    #include <fcntl.h>
    #include <errno.h>
    
    //  Constants
    #define stdout  1
    #define stderr  2
    
    //  Macros
    #define werror_exit     { werror(); return 1; }
    #define werr_exit(s)    { _write(stderr, (s), (unsigned int)strlen((s))); return 1; }
    
    //  Declarations
    extern void werror();
    extern void wnum(__int64 num);
    

    来源

    #include "readbinaryfile.h"
    
    int main(int argc, char **argv)
    {
        int     fhandle;
        __int64 fsize;
    
        // open binary file as read only. deny sharing write permissions. allow write permissions if new file
        if (_sopen_s(&fhandle, argv[1], _O_RDONLY | _O_BINARY, _SH_DENYWR, _S_IWRITE) == -1)
            werror_exit
        else if (fhandle == -1)
            werr_exit("\nERROR: file does not exist...\n")
    
        if (fsize = _filelengthi64(fhandle) == -1)
        {
            if (_close(fhandle) == -1)
                werror_exit
            werror_exit
        }
    
        if (_close(fhandle) == -1)
            werror_exit
    
        // write the file size to stdout
        wnum(fsize);
    
        return 0;
    }
    
    // fetch the string representation of the errno global variable and write it to stderr
    void werror()
    {
        char    bufstr[95];
        size_t  buflen = 95; // MSDN suggested number for errno string length
    
        strerror_s(bufstr, buflen, errno);
        _write(stderr, bufstr, (unsigned int)buflen);
    
        _set_errno(0);
    }
    
    // recursively write the ascii value of each digit in a number to stdout
    void wnum(__int64 num)
    {
        if (num / 10 == 0)
        {
            _write(stdout, &(num += 48), 1);
            return;
        }
    
        wnum(num / 10);
        _write(stdout, &((num %= 10) += 48), 1);
    }
    

    我尝试过将许多不同的文件路径传递给 argv[1] fsize 在所有这些情况下, fhandle 使用后被指定为值3 _sopen\u s() wnum() werror() . 谢谢你的帮助!

    1 回复  |  直到 6 年前
        1
  •  2
  •   IInspectable    6 年前

    _filelengthi64(fhandle) 不返回0。表达式 _filelengthi64(fhandle) == -1 但是,will(假设调用成功),然后将其分配给 fsize C operator precedence == 优先级高于 = . 必须使用括号来更改优先级:

    if ((fsize = _filelengthi64(fhandle)) == -1)
    {
        ...
    

    // Normal code flow
    fsize = _filelengthi64(fhandle);
    // Error handling code
    if (fsize == -1)
    {
        ...