C ++ ifstream long完整路径不工作 [英] C++ ifstream long full path not working

查看:101
本文介绍了C ++ ifstream long完整路径不工作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I would like to read a file from disk and during program execution using QDialog (Qt Widget) I choose the path to the file. Piece of code is very simple:

ifstream infile(path.c_str());

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

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

The problem arises depending on the location of the target file:


  • 如果文件的路径是D:\folder\file - 它读取文件和
    一切正常

  • 到文件是C:\Users\Rafał
    Surname\Desktop\folder\file - 无法打开文件

如何解决这个问题?

推荐答案

猜测你的机器的Windows ANSI GetACP )在您的名称中不包含字符ł

At a guess, your machine's Windows ANSI (the codepage returned by GetACP) does not contain the character "ł" in your name.

最简单的解决方案是不要在路径中使用这样的字符。

The simplest solution is to not use such character in the path.

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

Otherwise you can use wide paths, wchar_t based paths. Visual C++ support them even though standard C++ does not.

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

Alternatively, to make the code work also with g++, you can use the Windows API to translate the wide path to a short path, where each name is maximum 8 characters. The short folder and file names are alternates intended precisely for compatibility with non-Unicode software. However, while that works nicely and easily for the case at hand, namely opening a file, it's more complicated for creating a file.

最后,你可以使用Boost文件系统,这是非常相似的,如果不相同的功能,将成为C ++ 14的一部分。显然,一个版本/变体已经是Visual C ++运行时库的一部分。然而,一个问题是,它可能无法使用g ++,因为它依赖于Visual C ++中的上述宽路径支持(是的,几乎是一个悖论,获得库中有这样的要求在标准中)。

Finally, you can use Boost filesystem, which is very similar if not identical to the functionality that will become part of C++14. And apparently a version/variant is already part of the Visual C++ runtime library. A problem with that is, however, that it may not work with g++, since it relies on the aforementioned wide path support in Visual C++ (yes, it's almost a paradox, getting libraries with such requirements in the standard).

在g ++的标准库实现中有一些低级的Unicode路径支持,但是不提供 wchar_t based constuctors。我深入了一些旧的我的代码,并找到下面的代码。 cppx :: Syschar 是由我的代码定义的类型,它在Windows中具有 wchar_t 作为底层类型: p>

档案open_file.h

There is some low level Unicode path support in g++'s standard library implementation, but not anything like offering wchar_t based constuctors. I delved into some old code of mine and found the code below. cppx::Syschar is a type defined by my code, and it has wchar_t as underlying type in Windows:

#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

File "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

Of course this is an ofstream, not an ifstream.

在g ++中的支持示例,而你的问题的答案很可能涉及到使用Visual C ++中的宽路径支持,或使用Windows API,或者只是避免Unicode特定的字符,如上所述。

And again, it's just an example of the support in g++, while the answer to your question most likely involves either using the wide path support in Visual C++, or using the Windows API, or simply avoiding Unicode-specific characters, as discussed above.

利用Visual C ++宽路径支持,类似的 ofstream 实现可以简单如下:

Leveraging the Visual C++ wide path support a similar ofstream implementation can simply be like this:

#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

这篇关于C ++ ifstream long完整路径不工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆