C ++ ifstream long完整路径不工作 [英] C++ ifstream long full path not working
问题描述
我想从磁盘读取文件,并在程序执行期间使用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屋!