20

std::stringStackOverflowには、対または類似の質問がすでにいくつかあることは知っていstd::wstringますが、完全なソリューションを提案したものはありません。

良い答えを得るために、私は要件を定義する必要があります:

  • マルチプラットフォームの使用法、Windows、OS X、Linuxで動作する必要があります
  • UTF-8またはOSAPIで必要とされる他のタイプなど、プラットフォーム固有のUnicode文字列との間で変換するための最小限の労力。備考:サポートされているすべてのオペレーティングシステムでUnicode互換関数のみを使用することを期待しているため、コードページ変換のサポートは必要ありません。CFStringRefwchar_t *char*
  • 外部ライブラリが必要な場合、これはオープンソースであり、BSDのような非常にリベラルなライセンスの下にある必要がありますが、LGPLではありません。
  • printf形式の構文などを使用できます。
  • 文字列の割り当て/割り当て解除の簡単な方法
  • Unicode文字列はアプリケーションUIにのみ使用されると想定しているため、パフォーマンスはそれほど重要ではありません。
  • いくつかの例をいただければ幸いです

私は本当に、答えごとに1つの提案された解決策だけを感謝します。これを行うことによって、人々は彼らの好みの選択肢に投票することができます。複数の選択肢がある場合は、別の回答を追加してください。

あなたのために働いた何かを示してください。

関連する質問:

4

6 に答える 6

7

アプリケーションの内部でUTF-8を使用することを強くお勧めします。通常の古いものを使用するchar*std::string、データストレージに使用します。異なるエンコーディング(ASCII、UTF-16など)を使用するAPIとのインターフェースには、LGPLの下でライセンスされているlibiconvを使用することをお勧めします。

使用例:

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);
于 2010-01-10T17:19:37.577 に答える
5

Adam Rosenfieldの回答(+1)と同じですが、代わりにUTFCPPを使用します。

于 2010-01-10T18:19:42.833 に答える
3

私は最近、「ワイド文字列はUnicodeですよね?」という理由で、クロスプラットフォームプロジェクトにstd::wstringを使用することを決定したプロジェクトに参加していました。これは多くの頭痛の種につながりました:

  • wstringのスカラー値はどのくらいですか?回答:それはコンパイラの実装次第です。Visual Studio(Win)では、16ビットです。しかし、Xcode(Mac)では、32ビットです。
  • これにより、ネットワークを介した通信にUTF-16を使用するという不幸な決定につながりました。しかし、どのUTF-16ですか?UTF-16BE(ビッグエンディアン)とUTF16-LE(リトルエンディアン)の2つがあります。これについて明確にしないと、さらに多くのバグが発生しました。

プラットフォーム固有のコードを使用している場合は、プラットフォームのネイティブ表現を使用してAPIと通信するのが理にかなっています。ただし、プラットフォーム間で共有されるコード、またはプラットフォーム間で通信するコードについては、すべてのあいまいさを避け、UTF-8を使用してください。

于 2010-01-10T18:24:07.510 に答える
1

経験則:処理にはネイティブプラットフォームのUnicode形式(UTF-16またはUTF-32)を使用し、データ交換(通信、ストレージ)にはUTF-8を使用します。

すべてのネイティブAPIがUTF-16を使用している場合(たとえばWindowsの場合)、文字列をUTF-8として使用すると、すべての入力をUTF-16に変換し、Win APIを呼び出してから、回答をUTF-8に変換する必要があります。かなりの痛み。

しかし、主な問題がUIである場合、文字列は単純な問題です。より難しいのはUIフレームワークです。そのためには、wxWidgets(http://www.wxWidgets.org)をお勧めします。多くのプラットフォーム、成熟した(17年でまだ非常にアクティブ)、ネイティブウィジェット、Unicode、リベラルライセンスをサポートします。

于 2010-01-11T07:13:00.770 に答える
1

メモリ内のUTF16表現と、ハードディスクまたはワイヤ上のUTF-8または16を使用します。主な理由:UTF16の「文字」ごとのサイズは固定されています。これにより、文字列を操作する際の多くの作業(検索、部品の交換など)が簡素化されます。

UTF-8の唯一の理由は、「西洋/ラテン」文字のメモリ使用量が減少することです。この表現は、ディスクストレージまたはネットワーク経由の転送に使用できます。また、ディスク/ワイヤにロード/保存するときにバイトオーダーを気にする必要がないという利点もあります。

これらの理由を念頭に置いて、内部でstd :: wstringを使用するか、GUIライブラリがWidestringを提供している場合は、それを使用します(QTのQStringなど)。また、ディスクストレージの場合は、プラットフォームAPI用の小さなプラットフォームに依存しないラッパーを作成します。または、この変換に使用できるプラットフォームに依存しないコードがある場合は、unicode.orgをチェックしてください。


明確にするために:韓国語/日本語の文字は西洋/ラテン語ではありません。日本語は漢字の例です。そのため、ラテン文字セットについて説明しました。


UTF-16が1文字/2バイトではない場合。この仮定は、ベースの多言語平面上にある文字にのみ当てはまります(http://en.wikipedia.org/wiki/UTF16を参照)。それでもUTF-16のほとんどのユーザーは、すべての文字がBMP上にあると想定しています。アプリケーションでこれが保証されない場合は、UTF32に切り替えるか、UTF8に切り替えることができます。

それでもUTF-16は、多くのAPI(Windows、QT、Java、.NET、wxWidgetsなど)で上記の理由で使用されています。

于 2010-01-11T08:02:25.897 に答える
0

UTF-16は内に格納できますstd::string。したがって、原則として、すべてのプラットフォームで使用でき、プラットフォームで推奨されるエンコーディング(Linuxの場合はUTF-8、Windowsの場合はUTF-16など)std::string内に格納できます。これにより、C ++タイプレベルでは単純なものが残りますが、文字列のエンコーディングを追跡する必要があります。これは、アプリケーションが自己完結型の場合は単純な場合があり、相互運用する必要がある場合はそれほど単純ではない場合があります(ストレージ、ワイヤー形式を参照)。

UTF-16を内部に格納するリスクstd::stringは、遅かれ早かれ電話をかけ.c_str()、結果が最初の0で終わると解釈されるstd::string s = reinterpret_cast<char *>(L"hello")ことs[1]です。

于 2021-09-24T14:20:38.777 に答える