22

私はそのwstringように宣言しました:

// random wstring
std::wstring str = L"abcàdëefŸg€hhhhhhhµa";

私のソースファイルはであるため、リテラルはUTF-8でエンコードされます。

[編集:Mark Ransomによると、これは必ずしも当てはまるわけではなく、コンパイラが使用するエンコーディングを決定します。代わりに、UTF-8などでエンコードされたファイルからこの文字列を読み取ったと仮定します]

これをファイルの読み取りに取り入れたいと思います(テキストエディタが正しいエンコーディングに設定されている場合)

abcàdëefŸg€hhhhhhhµa

しかし、ofstreamあまり協力的ではなく(wstringパラメータを取ることを拒否します)、wofstreamおそらくロケールとエンコーディング設定を知る必要があります。このバイトセットを出力したいだけです。通常、これをどのように行いますか?

編集:クロスプラットフォームである必要があり、UTF-8であるエンコーディングに依存しないでください。たまたまにバイトのセットが格納されていてwstring、それらを出力したいと思っています。それはUTF-16またはプレーンASCIIである可能性が非常に高いです。

4

9 に答える 9

43

std::wstringあなたが必要とするためにstd::wofstream

std::wofstream f(L"C:\\some file.txt");
f << str;
f.close();
于 2013-08-14T08:11:13.663 に答える
15

std::wstringUTF-8ではなくUTF -16やUTF-32のようなものです。UTF-8の場合は、おそらく、を使用してstd::string、を介して書き出す必要がありますstd::cout。FWIWだけで、C ++ 0xにはUnicodeリテラルがあり、このような状況を明確にするのに役立ちます。

于 2010-10-29T16:39:05.787 に答える
8

ファイルをバイナリとして書き込んでみませんか。std :: ios::binary設定でofstreamを使用するだけです。その場合、編集者はそれを解釈できるはずです。最初のUnicodeフラグ0xFEFFを忘れないでください。ライブラリを使用して作成する方がよい場合は、次のいずれかを試してください。

http://www.codeproject.com/KB/files/EZUTF.aspx

http://www.gnu.org/software/libiconv/

http://utfcpp.sourceforge.net/

于 2010-10-29T16:57:19.433 に答える
5

C ++には、出力またはファイル書き込み時にワイド文字からローカライズ文字への変換を実行する手段があります。その目的にはcodecvtファセットを使用してください。

標準のstd::codecvt_byname、または非標準のcodecvt_facet実装を使用できます。

#include <locale>
using namespace std;
typedef codecvt_facet<wchar_t, char, mbstate_t> Cvt;
locale utf8locale(locale(), new codecvt_byname<wchar_t, char, mbstate_t> ("en_US.UTF-8"));
wcout.imbue(utf8locale);
wcout << L"Hello, wide to multybyte world!" << endl;

一部のプラットフォームでは、codecvt_bynameは、システムにインストールされているロケールに対してのみ変換を発行できることに注意してください。したがって、stackoverflowで「utf8codecvt」を検索し、リストされているカスタムcodecvt実装の多くの参照から選択することをお勧めします。

編集:OPは文字列がすでにエンコードされていると述べているので、彼がしなければならないのは、コードのすべてのトークンからプレフィックスLと"w"を削除することだけです。

于 2010-10-29T17:03:49.793 に答える
5

ここにあなたのために働くはずの(Windows特有の)解決策があります。基本的に、wstringUTF-8コードページに変換してからを使用しますofstream

#include < windows.h >

std::string to_utf8(const wchar_t* buffer, int len)
{
        int nChars = ::WideCharToMultiByte(
                CP_UTF8,
                0,
                buffer,
                len,
                NULL,
                0,
                NULL,
                NULL);
        if (nChars == 0) return "";

        string newbuffer;
        newbuffer.resize(nChars) ;
        ::WideCharToMultiByte(
                CP_UTF8,
                0,
                buffer,
                len,
                const_cast< char* >(newbuffer.c_str()),
                nChars,
                NULL,
                NULL); 

        return newbuffer;
}

std::string to_utf8(const std::wstring& str)
{
        return to_utf8(str.c_str(), (int)str.size());
}

int main()
{
        std::ofstream testFile;

        testFile.open("demo.xml", std::ios::out | std::ios::binary); 

        std::wstring text =
                L"< ?xml version=\"1.0\" encoding=\"UTF-8\"? >\n"
                L"< root description=\"this is a naïve example\" >\n< /root >";

        std::string outtext = to_utf8(text);

        testFile << outtext;

        testFile.close();

        return 0;
}
于 2010-10-29T16:39:44.243 に答える
0

しばらく前に同じ問題が発生し、ブログで見つけた解決策を書き留めました。特に関数が役立つかどうかを確認するためにチェックアウトすることをお勧めしますwstring_to_utf8

http://pileborg.org/b2e/blog5.php/2010/06/13/unicode-utf-8-and-wchar_t

于 2010-10-29T17:08:09.017 に答える
0

ワイドストリームはchar*変数のみを出力するため、c_str()メンバー関数を使用してを変換しstd::wstringてからファイルに出力してみてください。それならおそらくうまくいくはずですか?

于 2010-10-29T16:43:16.547 に答える
0

ポータブルコードを記述したい場合は、UTF-8でエンコードされたソースファイルを使用しないでください。ごめん。

  std :: wstring str = L "abcàdëefŸg€hhhhhhhµa";

(これが実際に基準を傷つけるかどうかはわかりませんが、そうだと思います。しかし、たとえ安全であるためには、そうすべきではありません。)

はい、純粋に使用しても機能しstd::ostreamません。wstringaをUTF-8に変換する方法はたくさんあります。私のお気に入りは、Unicode用InternationalComponentsを使用することです。それは大きなライブラリですが、素晴らしいです。あなたはあなたが将来必要とするかもしれないたくさんのエキストラと物を手に入れます。

于 2010-10-29T17:41:08.137 に答える
0

さまざまな文字エンコードを使用した私の経験から、ロード時にUTF-8のみを処理し、時間を節約することをお勧めします。1文字は1バイトから4までの範囲である可能性があるため、内部表現をUTF-8に格納しようとすると、苦痛の世界に陥ります。したがって、strlenのような単純な操作では、すべてのバイトを調べてlenを決定する必要があります。割り当てられたバッファ(charシーケンスの最初のバイトを確認することで最適化できますが、たとえば00..7fは1バイトのchar、c2..dfは2バイトのcharなどを示します)。

UTF-16を意味する場合、「Unicode文字列」をよく参照します。Windowsでは、wchar_tは固定の2バイトです。Windowsでは、wchar_tは単純に次のようになります。

typedef SHORT wchar_t;

完全なUTF-324バイト表現が必要になることはめったになく、非常に無駄です。ここでは、Unicode標準(5.0)で次のように述べています。

「平均して、すべてのUTF-16の99%以上が単一のコード単位を使用して表現されています... UTF-16は、コンパクトなサイズとBMPの外部で時折発生する文字を処理する機能の適切な組み合わせを提供します。」

つまり、内部表現としてwhcar_tを使用し、ロードおよび保存時に変換を実行します(必要であることがわかっている場合を除き、完全なUnicodeについて心配する必要はありません)。

実際の変換の実行に関しては、ICUプロジェクトをご覧ください。

http://site.icu-project.org/

于 2010-10-29T17:48:17.933 に答える