没有广泛 API 的可移植 UTF-8 接口(Windows 和 Unix)
Posted
技术标签:
【中文标题】没有广泛 API 的可移植 UTF-8 接口(Windows 和 Unix)【英文标题】:Portable UTF-8 Interface (Windows and Unix) without wide API 【发布时间】:2015-05-26 09:46:10 【问题描述】:我正在使用以下界面设置硬盘驱动器上文件的路径:
void setPath(const char* path);
此路径将用于基本文件 I/O。
例如,如果我提供一个包含中文字符的路径(例如,通过 QString::toUtf8()),这对 Unix 工作正常,但对于 Windows 当然不是,因为内部使用了 wchar/wstring API。
我现在正在寻找一种优雅的方式来使这个接口在基于 Windows 和 Unix 的系统上兼容 UTF-8。 有没有办法避免在基于 Windows 的系统上使用宽 API 并继续使用 std::string 和 std::ofstream() ?
在查看 boost::locale 之后,我觉得这可以处理 UTF-8 编码。这会是一种方法吗(例如,用它的 boost::ofstream() 对应物替换 std::ofstream ?)
const std::locale loc = generator.generate(std::locale(), "zh_CN.UTF-8");
std::locale::global(loc);
std::cout.imbue(std::locale());
boost::filesystem::path::imbue(std::locale())
感谢所有帮助。
【问题讨论】:
【参考方案1】:有没有办法避免在基于 Windows 的系统上使用宽 API
Windows API 不支持 UTF-8,除了少数选定的 API。很大程度上它只支持依赖于语言环境的 ANSI 和 UTF-16。要在不丢失数据的情况下支持 Unicode,您必须使用基于 UTF-16 的 API。
在将 UTF-8 字符串传递给 Windows API 函数时,您的接口需要在内部将其转换为 UTF-16,并在从 API 接收数据时将其从 UTF-16 转换为 UTF-8。没有其他办法。这属于您的底层平台特定逻辑,而不是更高层的公共接口。
并继续使用 std::string 和 std::ofstream() ?
您可以将std::string
用于UTF-8,并且有很多方法可以在std::string
UTF-8 和std::wstring
UTF-16 之间进行转换(C++11 中甚至还有类来处理它) .
Microsoft 在 Visual Studio 中对 std::ifstream
和 std::ofstream
进行了非标准扩展,以接受 UTF-16 文件名。其他供应商可能会也可能不会提供类似的功能。
【讨论】:
以上是关于没有广泛 API 的可移植 UTF-8 接口(Windows 和 Unix)的主要内容,如果未能解决你的问题,请参考以下文章