C ++ ifstream长完整路径不起作用[重复]

Posted

技术标签:

【中文标题】C ++ ifstream长完整路径不起作用[重复]【英文标题】:C++ ifstream long full path not working [duplicate] 【发布时间】:2014-05-31 10:44:03 【问题描述】:

我想从磁盘读取文件,并在使用 QDialog (Qt Widget) 执行程序期间选择文件的路径。一段代码很简单:

ifstream infile(path.c_str());

if (infile.is_open()) 
    //some code   

else
    //log it

问题的出现取决于目标文件的位置:

如果文件的路径是“D:\folder\file” - 它会读取文件并 一切正常 如果文件的路径是“C:\Users\Rafał Surname\Desktop\folder\file" - 无法打开文件

如何解决?

【问题讨论】:

'文件无法打开'您可能想使用std::ifstream::exceptions() 成员来获取更多信息,究竟出了什么问题。 @CodyGray:那里的答案非常不完整,并且选择的解决方案很旧,因此现在包含不正确的信息:“标准库中没有对 UTF-8 的直接支持”。跨度> 【参考方案1】:

猜测一下,您机器的 Windows ANSI(GetACP 返回的代码页)在您的名称中不包含字符 "ł"

最简单的解决方案是不在路径中使用此类字符。

否则,您可以使用 宽路径,基于 wchar_t 的路径。即使标准 C++ 不支持,Visual C++ 也支持它们。

或者,为了使代码也可以与 g++ 一起使用,您可以使用 Windows API 将宽路径转换为 ​​短路径,其中每个名称最多为 8 个字符。短文件夹和文件名是为了与非 Unicode 软件兼容而使用的替代名称。然而,虽然这对于手头的情况(即打开文件)工作得很好也很容易,但创建文件更复杂。

最后,您可以使用 Boost 文件系统,它与将成为 C++14 的一部分的功能非常相似,如果不完全相同的话。显然,版本/变体已经是 Visual C++ 运行时库的一部分。然而,一个问题是它可能不适用于 g++,因为它依赖于前面提到的 Visual C++ 中的宽路径支持(是的,在标准中获取具有此类要求的库几乎是一个悖论)。


在 g++ 的标准库实现中有一些低级 Unicode 路径支持,但不像提供基于 wchar_t 的构造函数。我深入研究了我的一些旧代码,并找到了下面的代码。 cppx::Syschar 是我的代码定义的类型,它在 Windows 中具有 wchar_t 作为基础类型:

文件“open_file.h”
#pragma once

#include <stdio.h>      // fopen        !!!Needs to be first for g++ 4.7.2.
#include <rfc/cppx/core/Syschar.h>      // cppx::Syschar etc.
#include <wchar.h>      // _wfopen

namespace x 
    using cppx::Syschar;

    inline auto open_file( char const* const path, char const* const options )
        -> FILE*
     return ::fopen( path, options ); 

    inline auto open_file( wchar_t const* const path, wchar_t const* const options )
        -> FILE*
     return _wfopen( path, options ); 

    inline auto open_file( Syschar const* path, Syschar const* options )
        -> FILE*
     return open_file( raw( path ), raw( options ) ); 
  // namespace zx
文件“ofstream.g++_compiler.h”
#pragma once
#include "open_file.h"                  // open_file
#include <ext/stdio_filebuf.h>          // __gnu_cxx::stdio_filebuf

namespace x 
    using cppx::Syschar;

    class ofstream
        : public std::ofstream
    
    private:
        __gnu_cxx::stdio_filebuf<char>  buf_;
        std::streambuf*                 p_original_buf_;

    public:
        ~ofstream()
        
            basic_ios::rdbuf( p_original_buf_ );
            buf_.close();
        

        ofstream( Syschar const* const filename )
            : std::ofstream()
            , buf_(
                open_file( filename, CPPX_U( "w" ) ),
                std::ios_base::out
                )
            , p_original_buf_( nullptr )
        
            p_original_buf_ = basic_ios::rdbuf( &buf_ );
        
    ;

  // namespace x

当然这是ofstream,而不是ifstream

再说一次,这只是 g++ 中支持的一个示例,而您的问题的答案很可能涉及使用 Visual C++ 中的宽路径支持,或使用 Windows API,或者只是避免使用 Unicode 特定字符,如上面已经讨论过了。

利用 Visual C++ 宽路径支持类似的ofstream 实现可以简单地像这样:

文件“ofstream.msvc_compiler.h”
#pragma once

#include <rfc/cppx/core/Syschar.h>      // cppx::Syschar etc.

#include <fstream>      // std::ofstream

namespace x 
    using cppx::Syschar;

    class ofstream
        : public std::ofstream
    
    public:
        // Other stuff, and ...
        ofstream( Syschar const* const filename )
            : std::ofstream( raw( filename ) )   // wchar_t, a Visual C++ extension.
        
    ;
  // namespace x

【讨论】:

【参考方案2】:

那是因为你的路径中有一个倾斜的“l”。它是一个 Unicode 字符。当前路径中的 Unicode 存在问题。 As far as I know,Visual Studio 中只有 open() 的流方法接受 wchar_t* 路径。

【讨论】:

以上是关于C ++ ifstream长完整路径不起作用[重复]的主要内容,如果未能解决你的问题,请参考以下文章

在firefox中以html上传文件时获取文件完整路径[重复]

文件路径太长无法删除

在 C++ 中按完整路径打开文件

React JS路由路径不起作用[重复]

带有长路径的git clone命令问题[重复]

C# WebApi - 在 HTTPRequest 中发送长文本不起作用