1

私の質問は人々を混乱させたようです。ここに具体的なものがあります:

私たちのコードは次のことを行います。

FILE * fout = _tfsopen(_T("丸穴種類.txt"), _T("w"), _SH_DENYNO);
_fputts(W2T(L"刃物種類\n"), fout);
fclose(fout);

MBCS ビルド ターゲットの下で、上記はコード ページ 932 の適切にエンコードされたファイルを生成します (これが実行されたとき、932 がシステムの既定のコード ページであったと仮定します)。

UNICODE ビルド ターゲットでは、上記は ???? でいっぱいのガベージ ファイルを生成します。

ソース コードを変更せずに、ビルド ターゲットが UNICODE の場合に上記を引き続き機能させるために、シンボルを定義するか、コンパイラ スイッチを使用するか、特別なヘッダーを含めるか、特定のライブラリへのリンクを使用したいと考えています。

以前の質問は次のとおりです。

FILE*ストリームは t (変換) または b (inary) モードで開くことができます。デスクトップ アプリケーションは、UNICODE または MBCS (Windows の場合) 用にコンパイルできます。

アプリケーションが MBCS 用にコンパイルされている場合、MBCS 文字列を「wt」ストリームに書き込むと、システム コード ページ (つまり、「非 Unicode ソフトウェア用」のコード ページ) の MBCS テキストを含む整形式のテキスト ファイルが生成されます。

私たちのソフトウェアは通常、ほとんどの文字列関数とストリーム関数の _t バージョンを使用するため、MBCS ビルドでは、出力は主に puts(pszMBString)または類似のものputcなど によって処理されpszMBStringます。逐語的に書き出されます(ただし、行末記号は自動的にマッサージされputsますgets )。

ただし、アプリケーションが UNICODE 用にコンパイルされている場合、MBCS 文字列を "wt" ストリームに書き込むと、ガベージ (大量の "?????" 文字) が発生します (つまり、UNICODE をシステムのデフォルト コード ページに変換してから書き込みます)。たとえば、 fwrite(pszNarrow, 1, length, stream)) を使用して、それをストリームに送信します。


ストリームをバイナリ モードで開くことができます。その場合、正しい MBCS テキストを取得できます...ただし、行末記号は PC スタイルの CR+LF ではなく、UNIX スタイルの LF のみになります。これは、バイナリ (非変換) モードでは、ファイル ストリームが LF->CR+LF 変換を処理しないためです。


しかし、私が本当に必要としているのは、MBCS 用にコンパイルするときに作成できたのとまったく同じファイルを作成できることです。システムのコード ページを使用して、行末記号と MBCS テキスト ファイルを修正します。

明らかに、ライン ターミネータを自分で手動で調整し、バイナリ ストリームを使用できます。ただし、これは非常に侵襲的なアプローチです。システム全体でテキスト ファイルを書き込むすべてのコードを見つけて、このすべてが正しく行われるように変更する必要があるからです。驚いたことに、UNICODE ターゲットは、私たちが使用していた MBCS ターゲットよりも馬鹿げている/能力が低いということです! 確かに、C ライブラリを切り替えて、「MBCS ビルドで行うのとまったく同じように、狭い文字列をそのまま出力しますが、行末記号を適切に処理する」と言う方法がありますか?!

4

3 に答える 3

0

UNICODE 用にコンパイルすると、c++ ライブラリは MBCS について何も認識しません。テキストを出力するためにファイルを開くと言うと、渡されたバッファを UNICODE バッファとして処理しようとします。

また、MBCS は可変長エンコーディングです。それを解析するために、C++ ライブラリは文字を繰り返し処理する必要がありますが、MBCS について何も知らない場合、これはもちろん不可能です。したがって、「行末記号を正しく処理する」ことは不可能です。

事前に文字列を準備するか、文字列をファイルに書き込む独自の関数を作成することをお勧めします。文字を1つずつ書くのが効率的かどうかはわかりませんが(測定が必要です)、そうでない場合は、文字列を断片的に処理して、\nを含まないすべてのものを一度に入れることができます.

于 2013-08-21T14:52:08.000 に答える