Mik*_*e M 10 c++ unicode boost boost-filesystem boost-locale
我想使用boost文件系统读取/写入具有unicode文件名的文件,在Windows上使用boost语言环境(mingw)(最后应该是平台独立的).
这是我的代码:
#include <boost/locale.hpp>
#define BOOST_NO_CXX11_SCOPED_ENUMS
#include <boost/filesystem.hpp>
#include <boost/filesystem/fstream.hpp>
namespace fs = boost::filesystem;
#include <string>
#include <iostream>
int main() {
std::locale::global(boost::locale::generator().generate(""));
fs::path::imbue(std::locale());
fs::path file("äöü.txt");
if (!fs::exists(file)) {
std::cout << "File does not exist" << std::endl;
}
fs::ofstream(file, std::ios_base::app) << "Test" << std::endl;
}
Run Code Online (Sandbox Code Playgroud)
在fs::exists真正检查与名称的文件äöü.txt.但是书面文件有名字äöü.txt.
阅读给出了同样的问题.使用fs::wofstream也没有帮助,因为这只是处理广泛的输入.
如何使用C++ 11和boost来解决这个问题?
编辑:发布错误报告:https://svn.boost.org/trac/boost/ticket/9968
澄清赏金: Qt很简单,但我想要一个只使用C++ 11和Boost,没有Qt和没有ICU的跨平台解决方案.
这可能很复杂,原因有两个:
C++源文件中有一个非ASCII字符串.此文字如何转换为a的二进制表示const char *将取决于编译器设置和/或OS代码页设置.
Windows仅通过UTF-16编码使用Unicode文件名,而Unix使用UTF-8作为Unicode文件名.
要在Windows上使用此功能,您可以尝试将文字更改为宽字符(UTF-16):
const wchar_t *name = L"\u00E4\u00F6\u00FC.txt";
fs::path file(name);
Run Code Online (Sandbox Code Playgroud)
要获得完整的跨平台解决方案,您必须从UTF-8或UTF-16字符串开始,然后确保将其正确转换为path::string_type类.
不幸的是,C++(以及Boost)ofstreamAPI不允许将wchar_t字符串指定为文件名.构造函数和open方法都是这种情况.
您可以尝试确保路径对象不会立即转换为const char *(通过使用C++ 11字符串API),但这可能无济于事:
std::ofstream(file.native()) << "Test" << std::endl;
Run Code Online (Sandbox Code Playgroud)
对于Windows工作,你也许能纷纷致电支持Unicode的Windows API的,CreateFileW,转换HANDLE到一个FILE *,然后使用FILE *该ofstream构造函数.这是在另一个StackOverflow答案中描述的,但我不确定ofstreamMinGW上是否存在该构造函数.
遗憾的是basic_ofstream,似乎不允许为自定义basic_filebuf类型进行子类化,因此FILE *转换可能是唯一的(完全不可移植的)选项.
您也可以使用内存映射I/O写入文件,而不是使用文件流.根据Boost如何实现它(它不是C++标准库的一部分),此方法可以使用Windows Unicode文件名.
这是一个使用对象打开文件的提升示例(取自另一个答案)path:
#include <boost/filesystem.hpp>
#include <boost/iostreams/device/mapped_file.hpp>
#include <iostream>
int main()
{
boost::filesystem::path p(L"b.cpp");
boost::iostreams::mapped_file file(p); // or mapped_file_source
std::cout << file.data() << std::endl;
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
10936 次 |
| 最近记录: |