我试图找出正确的方法来处理c++中的unicode。我想了解g++如何处理文字宽的字符串以及包含unicode字符的常规c字符串。我已经进行了一些基本测试,但并不太了解正在发生的事情。
wstring ws1(L"«¬.txt"); // these first 2 characters correspond to 0xAB, 0xAC
string s1("«¬.txt");
ifstream in_file( s1.c_str() );
// wifstream in_file( s1.c_str() ); // this throws an exception when I
// call in_file >> s;
string s;
in_file >> s; // s now contains «¬
wstring ws = textToWide(s);
wcout << ws << endl; // these two lines work independently of each other,
// but combining them makes the second one print incorrectly
cout << s << endl;
printf( "%s", s.c_str() ); // same case here, these work independently of one another,
// but calling one after the other makes the second call
// print incorrectly
wprintf( L"%s", ws.c_str() );
wstring textToWide(string s)
{
mbstate_t mbstate;
char *cc = new char[s.length() + 1];
strcpy(cc, s.c_str());
cc[s.length()] = 0;
size_t numbytes = mbsrtowcs(0, (const char **)&cc, 0, &mbstate);
wchar_t *buff = new wchar_t[numbytes + 1];
mbsrtowcs(buff, (const char **)&cc, numbytes + 1, &mbstate);
wstring ws = buff;
delete [] cc;
delete [] buff;
return ws;
}
似乎对wcout和wprintf的调用以某种方式破坏了流,并且只要将字符串编码为utf-8,调用cout和printf始终是安全的。
处理unicode的最佳方法是在处理之前将所有输入转换为width,然后在发送至outupt之前将所有输出转换为utf-8吗?
最佳答案
处理Unicode的最全面的方法是使用Unicode库(例如ICU)。 Unicode比一堆编码具有更多的方面。 C++不提供与这些额外方面一起使用的API。重症监护病房。
如果只想处理编码,那么一种可行的方法是正确使用内置C++方法。这包括打电话
std::setlocale(LC_ALL,
/*some system-specific locale name, probably */ "en_US.UTF-8")
在程序的开始。同样,不要在同一程序中使用
cout
/ printf
和wcout
/ wprintf
。 (您可以在同一程序中使用标准句柄以外的常规流对象和宽流对象)。将所有输入转换为width并将所有输出转换为utf-8是一种合理的策略。使用utf-8也很合理。在很大程度上取决于您的应用程序。 C++ 11具有内置的UTF8,UTF16和UTF32字符串类型,这些字符串类型在某种程度上简化了任务。
无论您做什么,都不要在字符串文字中使用扩展字符集的元素。 (在C++ 11中,可以在UTF8 / 16/32字符串文字中使用它们)。