开发者

Why does std::fopen and std::filebuf::open trim trailing space characters on Windows?

I stumbled on a strange problem when trying to port a piece of C++ code from MSWindows to linux (Mint10). I discovered that there was a little typo in a hard-coded filename : a trailing space char (\x20).

The code worked like a charm under Windows (Windows Vista/7开发者_运维知识库), but it had trouble to deal with the erroneous filename under linux. I discovered that both std::filebuf::open and std::fopen (and also boost::filesystem::filebuf) allow trailing space chars in filename under Windows (which I think is an incorrect behavior).

I tested the following code using MSVC2010 and MinGW under Win7 :

# include <iostream>
# include <fstream>
# include <string>
# include <cstdlib>

const std::string filename = "Z:\\Path\\To\\A\\File " ;  // one trailing space

int main(int, char * [])
{
    std::cout << "Testing with file : \"" << filename << "\"" << std::endl ;

    // Testing with std::filebuf::open
    std::filebuf fb ;
    fb.open(filename.c_str(), std::ios::in | std::ios::binary) ;
    if( fb.is_open() )
    {
        std::cout << "Using std::filebuf : Opened" << std::endl ;
        fb.close() ;
    }
    else
    {
        std::cout << "Using std::filebuf : Not opened" << std::endl ;
    }

    // Testing with std::fopen
    std::FILE * fp = std::fopen(filename.c_str(), "rb") ;
    if( fp )
    {
        std::cout << "Using std::fopen : Opened" << std::endl ;
        std::fclose(fp) ;
    }
    else
    {
        std::cout << "Using std::fopen : Not opened" << std::endl ;
    }
    return 0 ;
}

I verified that the file on the harddrive has no trailing space characters in the name. The file was successfully opened on Windows, but no luck to access it under linux if the filename isn't an exact match.

So I have a couple of questions :

  • Is this a normal behavior of the file API under Windows ? And is there some other gotchas ? I googled but found no reference on this case. (Maybe I'm a bad googler :))
  • How to write a code that works in a strict fashion with filenames ? Always trimming filenames before passing them to some file function isn't the solution for my case ; my current app have to list directories (using boost::filesystem::directory_iterator) and trimming filenames will break the app if the user provides filenames with trailing space chars (which is rare but allowed on many file systems).

Thanks for any advice !


Windows itself will strip the trailing blanks from a filename, it has nothing to do with the C++ function you use to open the file.

Here's one reference to this behavior in the Windows API function CreateFile: INFO: Filenames Ending with Space or Period Not Supported

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜