6

私はICUとコードプロジェクトのutf8のような小さなライブラリを知っています(正確な名前を忘れてください)が、これらのどれも私が望むものではありません。

私が本当に欲しいのはICUのようなものですが、より親しみやすい方法でまとめられています。

具体的には:

  • 完全なオブジェクト指向
  • c ++標準ストリームの実装、または少なくとも同じ役割を果たすもの。
  • ロケールに依存する方法で時刻や日付などをフォーマットできます(たとえば、英国ではdd / mm / yy、米国ではmm / dd / yy)。
  • 文字列の「内部」エンコーディングを選択できるので、たとえば、Windows APIおよびDirectXとの間で文字列をやり取りするときに、多くの変換を回避するために、WindowsでUTF-16を使用するようにすることができます。
  • エンコーディング間での文字列の簡単な変換

そのようなライブラリが存在しない場合、標準のc ++クラスを使用してICUをラップすることは可能ですか。たとえば、std::stringおよびstd::wstringと同じ使用法を持つustringを作成し、ストリームのバージョンを実装することもできます。 (最適には、既存のものと完全に互換性があります。つまり、std :: ostreamを期待する関数に渡すことができ、内部形式とascii(またはutf-8)の間の変換をオンザフライで実行します)?どれだけの作業が可能だとしたら?

編集:c ++ 0x標準を見て、utf8、utf16、utf32のリテラルに気づいたことは、標準ライブラリ(文字列、ストリームなど)がこれらのエンコーディングとそれらの間の変換を完全にサポートすることを意味しますか?もしそうなら、誰かがVisual Studioがそれらの機能をサポートするまでにどれくらいの時間がかかるかについて何か考えを持っていますか?

EDIT2:既存のc ++サポートの使用に関しては、ロケールとファセットのものを調べます。

私が遭遇した問題の1つは、ファイルI / Oのウィンドウの下で2バイトであるwchar_tの周りに定義されたストリームを使用する場合、ファイル自体にASCIIを使用しているように見えることです。

std::wofstream file(L"myfile.txt", std::ios::out);
file << L"Hello World!" << std::endl;

結果として、ファイルに次の16進数が含まれます
48 65 6C 6C 6F 20 57 6F 72 6C 64 0D 0A
これは、予想されるutf-16出力ではなく明らかにASCIIです:
FF FE 48 00 65 00 6C 00 6C 00 6F 00 20 00 57 00 6F 00 72 00 6C 00 64 00 0D 00 0A 00

4

6 に答える 6

3

私が本当に欲しいのは、ICUのようなものですが、よりフレンドリーな方法でラップされています

残念ながら、そのようなことはありません。彼らの API はそれほどひどいものではないので、多少の努力で慣れることができます。

時間、日付などをロケールに依存する方法でフォーマットできます (例: 英国では dd/mm/yy、米国では mm/dd/yy)。

std::localeクラスで完全にサポートされているので、使用方法を読んでください。ロケールを指定しstd::iostreamて、数値、日付を正しくフォーマットすることもできます。

エンコーディング間の文字列の簡単な変換

std::locale8 ビットのローカル エンコーディングをワイド エンコーディングに変換したり、その逆に変換するためのファセットを提供します。

たとえば、UTF-16を使用するようにすることができます

ICU は内部で utf-16wchar_tを使用し、win32 と wstring も utf-16 を使用します。他の OS では、ほとんどの実装では wchar_t を utf-32 として指定し、wstring は utf-32 を使用します。

備考:のサポートstd::localeは完全ではありませんが、文字操作に役立つ多くのツールが既に提供されています。

参照: http://www.cplusplus.com/reference/std/locale/

于 2009-05-07T16:12:45.560 に答える
2

これは、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"));
于 2009-05-07T16:55:05.927 に答える
2

私はいつもそのように働いています:

一部のエンコーディングでのバイト ストリーム -> ICU-> wistream -> stl & boost -> wostream -> ICU-> 一部のエンコーディングでのバイト ストリーム

于 2011-10-09T18:15:37.600 に答える
1

特定のロケールを指定することで、日付、時刻などのフォーマットを設定できます。独自のロールについては、基礎となるライブラリから必要なだけ取得して、いつでも可能です。

また、c++0x 標準を見て、utf8、utf16、および utf32 のリテラルに気づいたということは、標準ライブラリ (文字列、ストリームなど) がそれらのエンコードとそれらの間の変換を完全にサポートするということですか?

はい。ただし、これらは異なるデータ型であり、通常のwcharシーケンスやwstring.

もしそうなら、Visual Studio がそれらの機能をサポートするまでにどれくらいの時間がかかるか、誰にもわかりませんか?

私の知る限りでは、vc9 (VS2008) は一部の TR1 機能を部分的にしかサポートしていません。vc10 (VS2010) は、より優れたサポートが期待されます。

于 2009-05-07T15:54:18.613 に答える
-1

私は自分の小さなラッパーをしました。必要に応じて共有できます。

于 2009-05-07T16:41:08.063 に答える
-1

運が悪い。Dinkumware ライブラリが Unicode をサポートしていることは知っています。Web サイトのドキュメントを参照してください。私の知る限り、無料ではありません。

于 2009-05-07T16:44:50.583 に答える