在C++下处理Unicode字符串的最佳多平台方式是什么?

sor*_*rin 19 c++ string unicode multiplatform wstring

我知道已经有StackOverflow上有关的几个问题std::stringstd::wstring或类似,但没有人提出了一个完整的解决方案.

为了获得一个好的答案,我应该定义要求:

  • 多平台使用,必须适用于Windows,OS X和Linux
  • 最小的努力用于转换到/从平台特定的Unicode字符串CFStringRef,wchar_t *,char*为UTF-8或其他类型的,因为它们是由OS API必需的.备注:我不需要代码页转换支持,因为我希望在所有支持的操作系统上只使用Unicode兼容的函数.
  • 如果需要一个外部库,这个应该是开源的,并且在非常自由的许可下,如BSD但不是LGPL.
  • 能够使用printf格式语法或类似.
  • 简单的字符串分配/释放方式
  • 性能不是很重要,因为我假设Unicode字符串仅用于应用程序UI.
  • 一些例子可能会受到赞赏

我非常感谢每个答案提出一个解决方案,通过这样做,人们可以投票选择他们喜欢的替代方案.如果您有多个替代方案,请添加另一个答案.

请说明一些对你有用的东西.

相关问题:

Ada*_*eld 7

我强烈建议您在应用程序内部使用UTF-8,使用常规旧版char*std::string数据存储.为了与使用不同编码(ASCII,UTF-16等)的API接口,我建议使用libiconv,它是根据LGPL许可的.

用法示例:

class TempWstring
{
public:
  TempWstring(const char *str)
  {
    assert(sUTF8toUTF16 != (iconv_t)-1);
    size_t inBytesLeft = strlen(str);
    size_t outBytesLeft = 2 * (inBytesLeft + 1);  // worst case
    mStr = new char[outBytesLeft];
    char *outBuf = mStr;
    int result = iconv(sUTF8toUTF16, &str, &inBytesLeft, &outBuf, &outBytesLeft);
    assert(result == 0 && inBytesLeft == 0);
  }

  ~TempWstring()
  {
    delete [] mStr;
  }

  const wchar_t *Str() const { return (wchar_t *)mStr; }

  static void Init()
  {
    sUTF8toUTF16 = iconv_open("UTF-16LE", "UTF-8");
    assert(sUTF8toUTF16 != (iconv_t)-1);
  }

  static void Shutdown()
  {
    int err = iconv_close(sUTF8toUTF16);
    assert(err == 0);
  }

private:
  char *mStr;

  static iconv_t sUTF8toUTF16;
};

iconv_t TempWstring::sUTF8toUTF16 = (iconv_t)-1;

// At program startup:
TempWstring::Init();

// At program termination:
TempWstring::Shutdown();

// Now, to convert a UTF-8 string to a UTF-16 string, just do this:
TempWstring x("Entr\xc3\xa9""e");  // "Entrée"
const wchar_t *ws = x.Str();  // valid until x goes out of scope

// A less contrived example:
HWND hwnd = CreateWindowW(L"class name",
                          TempWstring("UTF-8 window title").Str(),
                          dwStyle, x, y, width, height, parent, menu, hInstance, lpParam);
Run Code Online (Sandbox Code Playgroud)

  • +1,我完全同意utf-8和`std :: string`. (4认同)
  • @Martin York不,它真的是UTF-16,而不是UCS-2.Windows以UCS-2开头,但今天大多数东西都是代理知道的(我知道有一件事情不是,可能会更多,但这些都是错误,总体而言是UTF-16) (3认同)
  • 那么*每个*平凡的字符串操作都需要转换? (2认同)
  • 你推荐的是与所有操作系统完全相反的方式.内部Win/Mac使用UTF-16(因为它是固定大小(不是真的,但是对于大多数实际用途)(实际上它的UCS-2但不告诉任何人)).存储以UTF-8完成. (2认同)

Kla*_*aim 5

与Adam Rosenfield回答(+1)相同,但我使用的是UTFCPP.