問題タブ [codecvt]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
c++ - C++ を使用した入力の Unicode 文字のインデックスとヒストグラム
各記号の出現回数と、それらがテキスト、単語、または行に表示される場所を数えます。多くの言語でこのような単語のリストがあります。
私がやろうとしているのは、各文字の出現と、それらが存在する、または一般的なテキスト内の位置を数えることです。また、共通の音節数を数えることができれば、それも役に立ちます。
これは、ユニコードで動作するようにした現在のコードです
これは私の元のコードでした
出力として取得しようとしているものの例
見つかった文字 K 次に見つかった出現回数 10 次に、前述のように見つかった各単語内の位置。
c++ - std::use_facet::out() で発生する可能性のあるバッファ オーバーフロー バグ
VC++10 std::locale オブジェクトでバッファ オーバーフローのバグを発見したと思います。私が何か間違ったことをしているかどうかについてのセカンドオピニオンに感謝します。
以下のコードは、問題を示すために単純化されています。wchar_t (UTF-16) 文字を (Windows) ANSI コード ページ 51949 (別名 EUC-KR) に変換しようとしています。2 バイト (DBCS) エンコーディングを使用するため、コード ページが選択されました。
「部分的」または「エラー」のステータスで失敗することを期待して、2 バイトの結果に対して意図的に単一の char バッファーを提供しています。
代わりに、ステータス「ok」を返し、バッファの末尾を超えて書き込み、終了しようとしたときに破損したスタックの例外を引き起こします。
デバッガーを使用して facet.out() 内にステップ インすると、次の関数の中にいることに気付きます (いくつかのレベルを下ります)。
問題は次のようです。
行if ((int)MB_CUR_MAX <= _Last2 - _Mid2)
で、MB_CURR_MAX (関数 ___mb_cur_max_func() に #defined である) は、DBCS char に期待される "2" ではなく、"1" を返しています。
この関数は、ファセットの初期化時に指定されたロケールではなく、グローバル ロケールにアクセスしているようです。
グローバル ロケールを次のように設定した場合:
それはすべて正常に動作します(そしてステータス「部分的」で失敗します)。
out()
したがって、この特定の実装では、オブジェクトの構築時に提供されたロケールではなく、MB_CUR_MAX を決定するためにグローバル ロケールを誤って使用しているように思われます。そのため、バッファ オーバーフロー バグが発生しています。
これで私の間違いを指摘できる人はいますか?
------------------------------
2013 年 5 月 20 日更新
---------------- --------------
これをバグ 787227 として MS に報告しました。
http://connect.microsoft.com/VisualStudio/feedback/details/787227/buffer-overflow-bug-in-std-use-facet-outを参照してください
------------------------------
2015 年 7 月 27 日更新
---------------- --------------
Microsoft から、このバグは Visual Studio 2015 の新しい RTM で修正されたというメールが届きました。 (Yay)
utf-8 - C++11でのUTF-8の読み取り/書き込み/印刷
私はC++11の新しいUnicode機能を調査してきましたが、他のC ++ 11エンコーディングの質問は非常に役立ちましたが、 cppreferenceの次のコードスニペットについて質問があります 。コードは、UTF-8エンコーディングで保存されたテキストファイルを書き込み、すぐに読み取ります。
私の質問は非常に単純ですが、なぜループにwchar_t
必要なのですか?for
文字u8
列リテラルは単純なものを使用して宣言できchar *
、UTF-8エンコーディングのビットレイアウトはシステムに文字の幅を通知する必要があります。UTF-8からUTF-32への自動変換があるようです(したがってwchar_t
)が、その場合、なぜ変換が必要なのですか?
c++ - コードポイントでの fstream ファイル サイズ
std::fstream のファイルのファイル サイズを取得するには多くの質問がありますが、それらはすべてファイル サイズをバイト単位で返し、ファイルが別のストリームで開かれている場合はエラーが発生しやすくなります。
バイトではなくコードポイントでファイルサイズを知りたいです。
これで、バイト単位の長さのみが返されstd::fstream::seekg(0,std::ios::end)
ます。std::fstream::tellg()
これは、ファイル内の UTF-16/32 文字の数を教えてくれません。その結果sizeof(wchar_t)
をあなたの言うことを聞いて割ってください。UTF-8 ファイルでは機能せず、移植可能ではありません。
さて、より技術的な考え方のために、私は独自のクラスを持つimbued
ストリームを持っています。ストリームへの 2 つのポインターを指定すると、長さを計算し、最大出力文字数または出力文字数のいずれかを返すメンバーがあります。ファイルのシークは、基本型ではなくシークすると思っていたでしょう。std::codecvt
std::codecvt
length()
codecvt::intern_type
char
ヘッダーを調べたfstream
ところ、seek infact でcodecvt
. また、VS2010 の私のバージョンでは、codecvt::length()
メンバーについても言及されていません。実際、 を呼び出すたびに、新しい文字列オブジェクトが作成され、 が返さcodecvt::in()
れるたびに 1 文字ずつサイズが増加します。代わりに、メンバーを呼び出して、呼び出しに適切なバッファーを提供しません。in()
partial
codecvt::max_length()
これは私の実装だけですか、それとも他の人も同じことを期待できますか? std::fstream
ロケールをフルに活用するために VS2012 用に書き直されましたか?
基本的に、テキスト ファイルを使用するたびに独自のファイル ハンドラーを作成する必要があることにうんざりしています。ファイルBOMfstream
が存在する場合は最初にそれを読み取り、正しいcodecvt
. char
次に、それらの文字を、wchar_t
またはコードが要求するものに変換します。また、エンコーディングの事前知識がわかっている場合は、構築時に alocale
を指定できるようにコーディングしたいと考えています。
内部バッファで直接作業した方がよいでしょうか? fstream クラスを書き直すのに影響しますか、それとも私が知らないいくつかのトリックがありますか?
unicode - std::fstream で UTF16 ファイルを書き込む
UTF-8エンコーディングを含むstd::stringをUTF-16ファイルにストリーミングできるように、std::fstreamを吹き込むことは可能ですか?
utf8-to-utf16 ファセットを使用して次のことを試しましたが、結果ファイルはまだ UTF-8 です。
codecvt_utf8_utf16 ファセットの参照は、UTF-16 ではなく UTF-8 ファイルの読み取りと書き込みに使用できることを示しているようです - それは正しいですか? もしそうなら、私がやりたいことを行う簡単な方法はありますか?
c++ - std::codecvt::unshift() が必要とする出力の最大サイズは?
私はカスタムファイルに取り組んでいますstreambuf
。今、シークのようにフラッシュしたいと思いfstream
ます。この時点で、出力用の配列の大きさを知りたいstd::codecvt::unshift()
ですか? std::codecvt::max_length()
によって返されるサイズで十分であるように私には思えます。私の仮定は正しいですか?
c++ - CR LF 変換を使用した C++ iostream UTF-16 ファイル I/O
CR LF 行区切り文字 (L"\r\n") を使用する utf-16 ファイルを読み書きしたい。C++ (Microsoft Visual Studio 2010) iostream の使用。ストリームに書き込まれたすべての L"\n" を透過的に L"\r\n" に変換したい。codecvt_utf16 ロケール ファセットを使用するには、fstream を ios::binary モードで開く必要があり、通常のテキスト モード \n から \r\n への変換が失われます。
BOOST のような追加のライブラリを必要としないソリューションが必要です。
c++ - オプション文字列に混合言語の文字が含まれていると、boost::program_option::store が例外をスローする
ASCII 文字のみを含む入力オプションで完全に機能する単純なコードがありますが、「エラー: 文字変換に失敗しました」というエラー メッセージで例外がスローされます。解決策はありますか?
背景情報:
これはソースコードです:
ブースト コードに足を踏み入れたところ、この関数 (boost_1_53_0\libs\program_options\src\convert.cpp) から例外がスローされたことがわかりました。
ブーストコードに足を踏み入れたとき、このステートメントがわかりました
実際には正常に動作します。utf-8 の文字列を wstring に戻すのに失敗するのは boost::program_options::store() 関数です。この失敗の理由は、現在のコード ページが非 ASCII 文字をサポートしていない可能性があります。現在のロケールが中国語ベースのロケールであれば、私のコードはうまく機能すると思います。私の問題の解決策はありますか?よろしくお願いします。
c++ - std::codecvt::do_in メソッドのオーバーロードと残りの基本メソッド
私は次do_in
のメソッドをオーバーロードしましたstd::codecvt
:
このように使用されます:
しかし、do_in
オーバーロードは呼び出されていません。正しくオーバーロードしましたか? ファセット呼び出しメソッドを作成するには、どのメソッドstd::codecvt<char, char, std::mbstate_t>
(およびどのように) を変更do_in
する必要がありますか?