Преобразовать wstring в строку, закодированную в UTF-8 - PullRequest
18 голосов
/ 05 декабря 2010

Мне нужно конвертировать между строкой и строкой. Я понял, что использование фасета codecvt должно сработать, но, похоже, он не работает для локали utf-8.

Моя идея заключается в том, что когда я читаю кодированный в utf-8 файл в символы, один символ utf-8 читается в два обычных символа (именно так работает utf-8). Я хотел бы создать эту строку utf-8 из представления wstring для библиотеки, которую я использую в своем коде.

Кто-нибудь знает, как это сделать?

Я уже пробовал это:

  locale mylocale("cs_CZ.utf-8");
  mbstate_t mystate;

  wstring mywstring = L"čřžýáí";

  const codecvt<wchar_t,char,mbstate_t>& myfacet =
    use_facet<codecvt<wchar_t,char,mbstate_t> >(mylocale);

  codecvt<wchar_t,char,mbstate_t>::result myresult;  

  size_t length = mywstring.length();
  char* pstr= new char [length+1];

  const wchar_t* pwc;
  char* pc;

  // translate characters:
  myresult = myfacet.out (mystate,
      mywstring.c_str(), mywstring.c_str()+length+1, pwc,
      pstr, pstr+length+1, pc);

  if ( myresult == codecvt<wchar_t,char,mbstate_t>::ok )
   cout << "Translation successful: " << pstr << endl;
  else cout << "failed" << endl;
  return 0;

, который возвращает 'fail' для локали cs_CZ.utf-8 и работает правильно для локали cs_CZ.iso8859-2.

Ответы [ 6 ]

70 голосов
/ 16 октября 2012

Код ниже может помочь вам:)

#include <codecvt>
#include <string>

// convert UTF-8 string to wstring
std::wstring utf8_to_wstring (const std::string& str)
{
    std::wstring_convert<std::codecvt_utf8<wchar_t>> myconv;
    return myconv.from_bytes(str);
}

// convert wstring to UTF-8 string
std::string wstring_to_utf8 (const std::wstring& str)
{
    std::wstring_convert<std::codecvt_utf8<wchar_t>> myconv;
    return myconv.to_bytes(str);
}
4 голосов
/ 05 декабря 2010

Какая у тебя платформа?Обратите внимание, что Windows не поддерживает локали UTF-8, поэтому это может объяснить причину неудачи.

Чтобы сделать это зависимым от платформы способом, вы можете использовать MultiByteToWideChar / WideCharToMultiByte в Windows и iconv в Linux.Возможно, вам удастся использовать магию усиления, чтобы сделать это независимо от платформы, но я сам не пробовал, поэтому не могу добавить об этой опции.

0 голосов
/ 16 февраля 2019

Вы можете использовать конвертер utf_to_utf в boost для получения формата char для хранения в std :: string

std::string myresult = boost::locale::conv::utf_to_utf<char>(mywstring);
0 голосов
/ 27 июля 2012

Библиотека Lexertl имеет итератор, который позволяет вам сделать это:

std::string str;
str.assign(
  lexertl::basic_utf8_out_iterator<std::wstring::const_iterator>(wstr.begin()),
  lexertl::basic_utf8_out_iterator<std::wstring::const_iterator>(wstr.end()));
0 голосов
/ 05 декабря 2010

C ++ не имеет представления о Unicode.Используйте внешнюю библиотеку, такую ​​как ICU (UnicodeString класс ) или Qt (QString класс ), обе поддерживают Unicode, включая UTF-8.

0 голосов
/ 05 декабря 2010

Что делает языковой стандарт, так это то, что он предоставляет программе информацию о внешней кодировке, но при условии, что внутренняя кодировка не изменилась.Если вы хотите вывести UTF-8, вам нужно сделать это из wchar_t, а не из char*.

Что вы можете сделать, это вывести их как необработанные данные (не строки), тогда их следует правильно интерпретироватьесли системный языковой стандарт - UTF-8.

Plus, при использовании (w)cout / (w)cerr / (w)cin необходимо указать языковой стандарт в потоке.

...