为什么在Windows上std::fopen和std::filebuf::open会裁剪尾随空格字符

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

本文关键字:std 裁剪 字符 open 空格 Windows fopen 为什么 filebuf      更新时间:2023-10-16

在尝试将一段c++代码从MSWindows移植到linux (Mint10)时,我偶然发现了一个奇怪的问题。我发现在硬编码的文件名中有一个小错别字:末尾有一个空格字符(x20)。

代码在Windows (Windows Vista/7)下工作得很好,但在linux下处理错误的文件名时遇到了麻烦。我发现std::filebuf::openstd::fopen(以及boost::filesystem::filebuf)都允许在Windows下的文件名中尾随空格字符(我认为这是一种不正确的行为)。

我在Win7下使用MSVC2010和MinGW测试了以下代码:

# 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 ;
}

我确认硬盘上的文件名称中没有尾随空格字符。该文件在Windows上成功打开,但如果文件名不完全匹配,则在linux下无法访问。

我有几个问题:

  • 这是Windows下文件API的正常行为吗?还有其他陷阱吗?我在谷歌上搜索了一下,但没有找到有关此案的资料。(也许我是一个糟糕的谷歌人:))
  • 如何写一个代码,工作在一个严格的时尚与文件名?在将文件名传递给某些文件函数之前总是修剪文件名并不是我这种情况的解决方案;我目前的应用程序必须列出目录(使用boost::filesystem::directory_iterator)和修剪文件名将打破应用程序,如果用户提供的文件名与尾部空格字符(这是罕见的,但允许在许多文件系统)。

谢谢你的建议

Windows本身会从文件名中去掉后面的空格,这与您用来打开文件的c++函数无关。

在Windows API函数CreateFile: INFO:以空格或句号结尾的文件名不受支持