难以置信的是Unicode,Boost,C++,codecvts

Joo*_*kia 12 c++ unicode boost codecvt

在C++中,我想使用Unicode来做事情.因此,在掉下Unicode的兔子洞之后,我终于陷入了混乱,头痛和地方的火车残骸.

但是在Boost中,我遇到了一个不幸的问题,即尝试使用Unicode文件路径并尝试使用带有Unicode输入的Boost程序选项库.我已经阅读了关于locales,codecvts,Unicode编码和Boost主题的任何内容.

我目前试图让事情发挥作用的是使用一个带有UTF-8字符串的codecvt并将其转换为平台的编码(POSIX上的UTF-8,Windows上的UTF-16),我一直在努力避免wchar_t.

我实际上最接近的是尝试使用Boost.Locale,在输出时从UTF-8字符串转换为UTF-32字符串.

#include <string>
#include <boost/locale.hpp>
#include <locale>

int main(void)
{
  std::string data("Testing, ?");

  std::locale fromLoc = boost::locale::generator().generate("en_US.UTF-8");
  std::locale toLoc   = boost::locale::generator().generate("en_US.UTF-32");

  typedef std::codecvt<wchar_t, char, mbstate_t> cvtType;
  cvtType const* toCvt = &std::use_facet<cvtType>(toLoc);

  std::locale convLoc = std::locale(fromLoc, toCvt);

  std::cout.imbue(convLoc);
  std::cout << data << std::endl;

  // Output is unconverted -- what?

  return 0;
}
Run Code Online (Sandbox Code Playgroud)

我想我还有其他一些转换工作使用宽字符,但我真的不知道我在做什么.我不知道这个工作的正确工具是什么.救命?

Joo*_*kia 11

好吧,经过几个月的努力,我已经明白了,我想在将来帮助别人.

首先,codecvt是错误的做法.Boost.Locale提供了一种在boost :: locale :: conv命名空间中转换字符集的简单方法.这是一个例子(其他一些不基于语言环境).

#include <boost/locale.hpp>
namespace loc = boost::locale;

int main(void)
{
  loc::generator gen;
  std::locale blah = gen.generate("en_US.utf-32");

  std::string UTF8String = "Tésting!";
  // from_utf will also work with wide strings as it uses the character size
  // to detect the encoding.
  std::string converted = loc::conv::from_utf(UTF8String, blah);

  // Outputs a UTF-32 string.
  std::cout << converted << std::endl;

  return 0;
}
Run Code Online (Sandbox Code Playgroud)

如您所见,如果将"en_US.utf-32"替换为"",则会在用户的语言环境中输出.

我仍然不知道如何让std :: cout一直这样做,但是Boost.Locale的translate()函数在用户的语言环境中输出.

对于使用UTF-8字符串跨平台的文件系统,似乎这是可能的,这里是如何做到这一点的链接.