C ++ ifstream long full path无法正常工作

时间:2014-05-31 10:44:04

标签: c++ qt

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

ifstream infile(path.c_str());

if (infile.is_open()) {
    //some code   
}
else
    //log it

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

  • 如果文件的路径是“D:\ folder \ file” - 它会读取文件和 一切都还好
  • 如果文件的路径是“C:\ Users \Rafał 姓氏\桌面\文件夹\文件“ - 无法打开文件

如何解决这个问题?

2 个答案:

答案 0 :(得分:8)

猜测一下,您机器的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作为基础类型:

File" 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
文件&#34; ofstream.g ++ _ compiler.h&#34;
#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实现可以像这样:

File&#34; ofstream.msvc_compiler.h&#34;
#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

答案 1 :(得分:0)

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