ここから本文です

visualstudio2010でWIN32APIの勉強を行っているときに void write(){ TCHAR st...

nan********さん

2014/9/1322:51:22

visualstudio2010でWIN32APIの勉強を行っているときに

void write(){
TCHAR str[64];

HANDLE fl;static DWORD g;
fl=CreateFile(TEXT("TEST.txt"),GENERIC_READ|GENERIC_WRITE,0,0,OPEN_ALWAYS,FILE_ATTRIBUTE_NORMAL,0);
if(fl==(HANDLE)-1){
MessageBox(0,0,0,0);
}
ReadFile(fl,str,6,&g,0);
*(str+g)='\0';
MessageBox(0,str,0,0);
}
と入力してコンパイルすると

下記の画像のようになってしまって、
文字セットを「Unicode文字セットを使用する」
から「設定なし」や「マルチバイト文字を使用する」等に
切り替えるとちゃんと「debug」と出力されるようになりました.

ですが、どうして設定を変えると出力できたのかがわかりません。
どなたか教えていただけると幸いです.
※TEST.txtには
「debug」とだけ入力してあります。
※ウィンドウクラスの登録などは省略してます

test.txt&quot,TCHAR str,static DWORD g,MessageBox,void write,Unicode,CreateFileA

閲覧数:
87
回答数:
3

違反報告

ベストアンサーに選ばれた回答

k03********さん

2014/9/1323:01:41

nanstoodさん

1.
どちらかにする。
a.
マルチバイト文字を使用する

b.
Unicode文字セットを使用する
"TEST.txt"の内容も、Unicodeにかえる。

2.
void write(){
TCHAR str[64];

HANDLE fl;static DWORD g;
fl=CreateFile(TEXT("TEST.txt"),GENERIC_READ|GENERIC_WRITE,0,0,OPEN_ALWAYS,FILE_ATTRIBUTE_NORMAL,0);
if(fl==(HANDLE)-1){
MessageBox(0,0,0,0);
return;//
}
ReadFile(fl,str,6,&g,0);
*(str+g)='\0';
MessageBox(0,str,0,0);
//ファイルを閉じる。
}

この回答は投票によってベストアンサーに選ばれました!

ベストアンサー以外の回答

1〜2件/2件中

並び替え:回答日時の
新しい順
|古い順

2014/9/1421:40:55

CreateFile、MessageBoxはCreateFileA/CreateFileW、MessageBoxA/MessageBoxWというAPIがマクロ定義で切り替えられるようになっています。
末尾にAとつくのはマルチバイト用、WとつくのはUnicode用です。

ReadFileで読み取ったファイルがマルチバイトだからUnicodeに設定してビルドすると文字が正しく表示できないのです。
ここでいうUnicodeとはUTF-16LEのことだと思って差し支え有りません。
たとえASCIIコードでも2バイト単位となるわけです。


特にUnicode対応アプリでなくて良いなら、マルチバイトでビルドして、TCHARを使用せずにcharを使うようにします。
TEXT()マクロも不要です。

何故かと言えば、UnicodeでビルドするとTCHARはwchar_tに、TEXT()マクロはL""に置き換わるからです。

Unicode対応にしたいなら、ファイルを読み出す処理においてマルチバイトをUTF-16LEに変換する必要があります。
MultiByteToWideChar()について調べるといいでしょう。

プロフィール画像

カテゴリマスター

n2q37_cppさん

2014/9/1411:22:25

①「Unicode文字セットを使用する」
②「設定なし」
③「マルチバイト文字を使用する」

これで切り替わるのはプログラムの動作です。でも、ファイルの内容は変わらない。それが原因です。

ご提示のプログラム中に次の記述がありますよね。

TCHAR、CreateFile、MessageBox、TEXT("TEST.txt")

これらが次のように変わります。

① wchar_t、CreateFileW、MessageBoxW、L"TEST.txt"
② char、CreateFileA、MessageBoxA、"TEST.txt"
③ char、CreateFileA、MessageBoxA、"TEST.txt"

で、今回の事象ですが TCHAR のところが問題です。ファイル中の文字データと①、②、③の設定は無関係ですよね。設定はビルドに影響を与えるわけだけど、それと関係なくファイルはありのままの姿で存在しているわけで。

『TEST.txtには「debug」とだけ入力してあります』とのことで、特別な言及が無いところから見ると ANSI 文字セットということでしょう。

とすると、ファイル中の文字データは char 型で見るのが正解。wchar_t 型、つまり Unicode で見ちゃダメってことです。Unicode で書かれていないものを Unicode だと思ってみてしまうと、変な文字列になってしまうということですよ。

《修正》

2箇所直します。そうすれば①、②、③の設定には関係なく正しく動作しますよ。

【修正前】TCHAR str[64];
【修正後】char str[64];

【修正前】MessageBox(0,str,0,0);
【修正後】MessageBoxA(0,str,0,0);


《備考》

現在、①の設定が主流です。昔は③でした。②の設定は外国用。日本(中国、韓国も含め)では使用されません。

OS とのやり取り、ライブラリ関数の利用、この2点において Unicode を使用する場合は①、シフトJIS を使用するのなら③です。いずれの場合も、既存データの読み書きについては関係ありません。いや、関係ないというより、関連を持たせてはダメ。TCHAR 型にしてはダメってことです。

みんなで作る知恵袋 悩みや疑問、なんでも気軽にきいちゃおう!

Q&Aをキーワードで検索:

Yahoo! JAPANは、回答に記載された内容の信ぴょう性、正確性を保証しておりません。
お客様自身の責任と判断で、ご利用ください。
本文はここまでです このページの先頭へ

「追加する」ボタンを押してください。

閉じる

※知恵コレクションに追加された質問は選択されたID/ニックネームのMy知恵袋で確認できます。

不適切な投稿でないことを報告しました。

閉じる