这真的取决于平台,Unicode很让人头疼。这取决于您使用哪个编译器。对于来自MS(VS2010或更早版本)的旧编译器,您需要使用MSDN中描述的API。此测试示例将创建一个名为您遇到问题的文件,然后将其重命名。
#include <string>
#include <tchar.h>
#include <windows.h>
using namespace std;
std::string utf8_encode(const std::wstring &wstr)
{
if( wstr.empty() ) return std::string();
int size_needed = WideCharToMultiByte(CP_UTF8, 0, &wstr[0], (int)wstr.size(), NULL, 0, NULL, NULL);
std::string strTo( size_needed, 0 );
WideCharToMultiByte (CP_UTF8, 0, &wstr[0], (int)wstr.size(), &strTo[0], size_needed, NULL, NULL);
return strTo;
}
std::wstring utf8_decode(const std::string &str)
{
if( str.empty() ) return std::wstring();
int size_needed = MultiByteToWideChar(CP_UTF8, 0, &str[0], (int)str.size(), NULL, 0);
std::wstring wstrTo( size_needed, 0 );
MultiByteToWideChar (CP_UTF8, 0, &str[0], (int)str.size(), &wstrTo[0], size_needed);
return wstrTo;
}
int _tmain(int argc, _TCHAR* argv[] ) {
std::string pFileName = "C:\\This \xe2\x80\x93 by ABC.txt";
std::wstring pwsFileName = utf8_decode(pFileName);
HANDLE hf = CreateFileW( pwsFileName.c_str() ,
GENERIC_READ | GENERIC_WRITE,
0,
0,
CREATE_NEW,
FILE_ATTRIBUTE_NORMAL,
0);
CloseHandle(hf);
MoveFileW(utf8_decode("C:\\This \xe2\x80\x93 by ABC.txt").c_str(), utf8_decode("C:\\This \xe2\x80\x93 by ABC 2.txt").c_str());
}
这些辅助函数仍然存在问题,以便您可以拥有一个空终止的字符串。
std::string utf8_encode(const std::wstring &wstr)
{
std::string strTo;
char *szTo = new char[wstr.length() + 1];
szTo[wstr.size()] = '\0';
WideCharToMultiByte(CP_UTF8, 0, wstr.c_str(), -1, szTo, (int)wstr.length(), NULL, NULL);
strTo = szTo;
delete[] szTo;
return strTo;
}
std::wstring utf8_decode(const std::string &str)
{
std::wstring wstrTo;
wchar_t *wszTo = new wchar_t[str.length() + 1];
wszTo[str.size()] = L'\0';
MultiByteToWideChar(CP_UTF8, 0, str.c_str(), -1, wszTo, (int)str.length());
wstrTo = wszTo;
delete[] wszTo;
return wstrTo;
}
转换字符大小问题...调用WideCharToMultiByte时将目标缓冲区大小设置为0允许获取所需的转换字符大小。然后它会返回所需的目标缓冲区字节数。所有这些代码操作解释了为什么像Qt这样的框架具有支持基于Unicode的文件系统的复杂代码。实际上,消除您所有可能出现的错误的最佳经济有效方法是使用此类框架。
适用于VS2015
std::string _old = u8"D:\\Folder\\This \xe2\x80\x93 by ABC.txt"s
根据他们的文档,我无法检查那个。
针对mingw。
std::string _old = u8"D:\\Folder\\This \xe2\x80\x93 by ABC.txt";
std::cout << _old.data();
输出包含正确的文件名...但对于文件 API,您仍需要进行适当的转换
u8"This – by ABC.txt"
吗? - Jean-François Fabre