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
作为基础类型:
#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
实现可以简单地像这样:
#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长完整路径不起作用[重复]的主要内容,如果未能解决你的问题,请参考以下文章