dポイントプレゼントキャンペーン実施中!

お世話になります。
UNICODE文字列について上手くいかない部分があったので質問します。
(1)ANSI文字コードのテキストファイルをfgetws関数で読み込む
(2)読み込んだ文字列をID3DXFont::DrawTextWメソッドで描画
以上のことを行うと、1バイト文字(半角文字)はきちんと表示されるのに対し、2バイト文字は化けてしまいます。
きちんと表示されるようにするにはどうすれば良いでしょうか?

開発環境:Visual Studio 2005 C++
開発言語:C/C++(Win32API)+DirectX9.0b

ご存知の方がいましたら、よろしくお願いします。

A 回答 (7件)

#1さんの回答について、念のため少し指摘しておくと...



fgetws関数は、「UNICODE 文字列のファイルから UNICODE の文字列を読み込むだけ」という代物ではありません。読み込み対象となるファイルは、あくまでも多バイト文字の並びが格納されていることを想定しています。そして、読み込み際に、setlocale関数で設定されたロケールに基づいて、ワイド文字列への変換が行われます。
    • good
    • 0

ISO/IEC9899では、fgetws自体にbinary streamに対する特別な規定はありません。



また、textであろうがbinaryであろうが、基本的にファイルはマルチバイトを仮定してます。
[Although both text and binary wide-oriented streams are conceptually sequences of wide characters,
the external file associated with a wide-oriented stream is a sequence of multibyte characters, ...]

また。文字(列)入出力関数では以下の変換を規定してます。
[The wide character input functions read multibyte characters from the stream and convert
them to wide characters as if they were read by successive calls to the fgetwc function.]
# the streamはwide-oriented streamにかかります。

標準仕様は、MBSの読み出しに変換を要求してますが、
「UNICODEが読めてはいけない」規定はありませんので、
MSの実装がこのような仕様でもアリな気がしますが、
すべての処理系がこのような動作をする保証はないかと思います。
# 「バイナリの入出力は一切無変換」の処理系だと、このような動作をする気はしますが、
# 少なくとも、私はこの実装を強制する規定は見つけてません。
# 「fgetwsが常にマルチバイトを仮定して変換を試みる(そしておそらく失敗する)」処理系があってもよさそうに思います。
    • good
    • 0
この回答へのお礼

一日で7件もの回答、ありがとうございました。
誠に失礼ながら、皆さんのお礼をまとめてさせていただきたいと思います。

結局、_tsetlocale(LC_CTYPE,TEXT(""));を_fgetts関数の前に挿入することで解決しました。
以前はfgets関数を使用していたのでロケールという概念について無知だったためのミスでした。
おかげさまで上手く動きました。

C#はデフォルトでUNICODEなのに対し、C/C++は後にUNICODEに対応したものですから、VisualStudioの仕様もなかなか難しいですね。
もう少し詳しく勉強したいと思います。
ありがとうございました。

お礼日時:2007/01/29 21:39

Microsoft の fgetws() のマニュアルには,入力ストリームが



・テキストモードの場合:マルチバイト文字列を読み出し,(ロケールに従って) ワイド文字列に変換する.
・バイナリモードの場合:Unicode 文字列を読み出す.変換は行われない.

と書かれていますが,後者は MS の独自仕様なんでしょうか?


テキスト モードとバイナリ モードの Unicode(TM) ストリーム入出力
http://msdn.microsoft.com/library/ja/default.asp …
    • good
    • 0

既にかかれてますが、fgetwsは


「あくまでも多バイト文字の並びが格納されていることを想定しています。<中略>ワイド文字列への変換が行われます。」
平たく言うと、「マルチバイト文字列のファイル(WindowsならShift-JISが普通。Linuxだと物によりEUCやUTF-8あたり)で書かれたファイルを、
ワイド文字(大抵はUNICODE)の文字列に変換して読み出す」ものなので、
「UNICODEのファイルを読んでも巧く動きません」。
自分で変換がいるのは、むしろファイルがUNICODE等の時です。
# ちなみに、ワイド文字の出力も、読み出し同様にロケールに従った変換が行われます。(ファイルはワイド文字になりません)
    • good
    • 0

★jacta さんへ


・ロケールの設定をすると『fgetws』関数でも文字列の変換が行われるんですか。
・お勉強になりました。

★ketaki さんへ
・というわけで私が紹介した『MultiByteToWideChar』関数を使うよりも『setlocale』関数で
 文字列を『fgetws』関数で読み込んだ方が簡単のようです。
・以上。おわり。

参考URL:http://www.bohyoh.com/CandCPP/C/Library/setlocal …
    • good
    • 0

ロケールの設定は正しく行っていますか?

    • good
    • 0

★ANSI文字コードのファイルを fgets 関数で読み込む。


・もともと『ANSI文字コード?』→『シフトJISコード』で書かれたファイルならば
 『fgets』関数で一旦読み込んでから、UNICODE 文字列に変換する処理をした後に
 DrawTextW メソッドで描画しないと文字化けするのは当然だと思います。
・私は『fgetws』関数は使ったことはありませんが、この関数は UNICODE 文字列の
 ファイルから UNICODE の文字列を読み込むだけですから文字コードの変換は質問者
 さんがご自分で行って下さい。

アルゴリズム:
(1)『シフトJISコード』で書かれたファイルを『fgets』関数で読み込む
(2)読み込んだ文字列を UNICODE 文字列に変換する
(3)変換した文字列を ID3DXFont::DrawTextW メソッドなどで描画する

最後に:
・『MultiByteToWideChar』関数は、ANSI 文字列などから Unicode 文字列に変換
・『WideCharToMultiByte』関数は、Unicode 文字列から ANSI 文字列などに変換
・以上。おわり。
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人はこんなQ&Aも見ています