C++ unicode вопросы

$lines = (Get-Content $file | Measure-Object -Line).Lines
6
задан ST3 14 September 2013 в 19:21
поделиться

5 ответов

Вот как я использую ICU для преобразования между std :: string (в UTF-8) и std :: wstring

/** Converts a std::wstring into a std::string with UTF-8 encoding.
 */
template < typename StringT >
StringT utf8 ( std::wstring const & rc_string );

/** Converts a std::String with UTF-8 encoding into a std::wstring.
 */
template < typename StringT >
StringT utf8 ( std::string const & rc_string );

/** Nop specialization for std::string.
 */
template < >
inline std::string utf8 ( std::string const & rc_string )
{
  return rc_string;
}

/** Nop specialization for std::wstring.
 */
template < >
inline std::wstring utf8 ( std::wstring const & rc_string )
{
  return rc_string;
}

template < >
std::string utf8 ( std::wstring const & rc_string )
{
  std::string result;
  if(rc_string.empty())
    return result;

  std::vector<UChar> buffer;

  result.resize(rc_string.size() * 3); // UTF-8 uses max 3 bytes per char
  buffer.resize(rc_string.size() * 2); // UTF-16 uses max 2 bytes per char

  UErrorCode status = U_ZERO_ERROR;
  int32_t len = 0;

  u_strFromWCS(
    &buffer[0],
    buffer.size(),
    &len,
    &rc_string[0],
    rc_string.size(),
    &status
  );
  if(!U_SUCCESS(status))
  {
    throw XXXException("utf8: u_strFromWCS failed");
  }
  buffer.resize(len);

  u_strToUTF8(
    &result[0],
    result.size(),
    &len,
    &buffer[0],
    buffer.size(),
    &status
  );
  if(!U_SUCCESS(status))
  {
    throw XXXException("utf8: u_strToUTF8 failed");
  }
  result.resize(len);

  return result;
}/* end of utf8 ( ) */


template < >
std::wstring utf8 ( std::string const & rc_string )
{
  std::wstring result;
  if(rc_string.empty())
    return result;

  std::vector<UChar> buffer;

  result.resize(rc_string.size());
  buffer.resize(rc_string.size());

  UErrorCode status = U_ZERO_ERROR;
  int32_t len = 0;

  u_strFromUTF8(
    &buffer[0],
    buffer.size(),
    &len,
    &rc_string[0],
    rc_string.size(),
    &status
  );
  if(!U_SUCCESS(status))
  {
    throw XXXException("utf8: u_strFromUTF8 failed");
  }
  buffer.resize(len);

  u_strToWCS(
    &result[0],
    result.size(),
    &len,
    &buffer[0],
    buffer.size(),
    &status
  );
  if(!U_SUCCESS(status))
  {
    throw XXXException("utf8: u_strToWCS failed");
  }
  result.resize(len);

  return result;
}/* end of utf8 ( ) */

Использовать это очень просто:

std::string s = utf8<std::string>(std::wstring(L"some string"));
std::wstring s = utf8<std::wstring>(std::string("some string"));
2
ответ дан 17 December 2019 в 04:51
поделиться

Не повезло. Я знаю, что библиотеки Dinkumware предлагают некоторую поддержку Unicode - вы можете посмотреть документацию на их веб-сайте. AFAIK, это не бесплатно.

-1
ответ дан 17 December 2019 в 04:51
поделиться

Я сделал свою маленькую обертку. Я могу поделиться, если хочешь.

-1
ответ дан 17 December 2019 в 04:51
поделиться

Форматирование даты, времени и т. д. можно сделать, указав конкретную локаль. Что касается прокрутки собственного - это всегда возможно, взяв столько или меньше из базовой библиотеки, сколько вам нужно.

Также, взглянув на стандарт c ++ 0x и заметив литералы для utf8, utf16 и utf32, действительно это означает, что стандартная библиотека (например, строки, потоки, и т.д.) будут полностью поддерживать эти кодировки и преобразование между ними?

Да. Но обратите внимание, что это разные типы данных, а не обычная последовательность wchar или wstring .

Если да, то кто-нибудь знает, сколько времени пройдет, пока Visual Studio не будет поддерживать эти функции ?

Насколько мне известно: vc9 (VS2008) имеет только частичную поддержку некоторых функций TR1. Ожидается, что vc10 (VS2010) получит лучшую поддержку.

1
ответ дан 17 December 2019 в 04:51
поделиться

Что мне действительно нужно, так это что-нибудь вроде ICU, но в более дружественной форме

К сожалению, такого нет. Их API не ТАК ужасен, так что вы можете привыкнуть к нему, приложив некоторые усилия.

Может форматировать время, даты и т. Д. В зависимости от локали (например, дд / мм / гг в Великобритании и мм / дд / гг в НАС).

Он полностью поддерживается в классе std :: locale , узнайте, как его использовать. Вы также можете указать языковой стандарт для std :: iostream , чтобы он правильно форматировал числа и даты.

Простое преобразование строк между кодировками

std :: locale предоставляет фасеты для покрытия 8-битных локальных кодирование в широкую единицу и обратно.

поэтому я могу, например, использовать UTF-16

ICU внутренне использует utf-16, win32 wchar_t и wstring также используют utf-16, в других операционных системах большинство реализаций выдает wchar_t как utf-32, а wstring использует utf-32.

Примечания: Поддержка std :: locale не идеальна, но уже дает много инструментов, которые полезны для манипуляций с символами.

См .: http://www.cplusplus.com/reference/std/locale/

3
ответ дан 17 December 2019 в 04:51
поделиться
Другие вопросы по тегам:

Похожие вопросы: