【发布时间】:2015-08-30 00:22:44
【问题描述】:
考虑以下代码:
#include <iostream>
#include <boost\locale.hpp>
#include <Windows.h>
#include <fstream>
std::string ToUtf8(std::wstring str)
{
std::string ret;
int len = WideCharToMultiByte(CP_UTF8, 0, str.c_str(), str.length(), NULL, 0, NULL, NULL);
if (len > 0)
{
ret.resize(len);
WideCharToMultiByte(CP_UTF8, 0, str.c_str(), str.length(), &ret[0], len, NULL, NULL);
}
return ret;
}
int main()
{
std::wstring wfilename = L"D://Private//Test//एउटा फोल्दर//भित्रको फाईल.txt";
std::string utf8path = ToUtf8(wfilename );
std::ifstream iFileStream(utf8path , std::ifstream::in | std::ifstream::binary);
if(iFileStream.is_open())
{
std::cout << "Opened the File\n";
//Do the work here.
}
else
{
std::cout << "Cannot Opened the file\n";
}
return 0;
}
如果我正在运行该文件,我将无法打开该文件,从而进入else 块。即使使用boost::locale::conv::from_utf(utf8path ,"utf_8") 而不是utf8path 也不起作用。如果我考虑使用wifstream 并使用wfilename 作为其参数,则该代码有效,但我不想使用wifstream。有什么方法可以打开名称为utf8 编码的文件?我正在使用Visual Studio 2010。
【问题讨论】:
-
没有任何底层 Windows API 使用 UTF8。 std::ifstream 最终会调用 CreateFileA 或 CreateFileW 来打开文件,这些函数都不是 UTF8。
-
所以如果我要使用
ifstream我应该如何更改代码以使其工作。我应该使用wstring -
问题是我正在尝试使代码跨平台。由于 Linux 已经支持 unicode,如果我使用
ifstream,代码应该可以工作。我该如何应对这种情况? -
这取决于您的标准库实现。我熟悉的一个,实际上是不可能的,您不能将 iostreams 用于可能具有非 8 位文件名的文件。
-
所以我唯一的选择是使用
ifdefs并使用wstring用于Windows 和string用于Linux 操作系统吗?还有其他方法吗?