- ベストアンサー
winsock recvでの文字化け
- Winsockを使用してサーバからのテキストを取得するプログラムで、文字エンコーディングがShift_JIS以外のページで文字化けする問題が発生しています。
- recv関数で取得した文字列が既に文字化けしていることが確認されており、取得した文字列をテキストファイルに出力する際も文字化けした状態で書き込まれています。
- 問題の部分のコードを示しており、recv関数やファイルの書き込み処理が正しく行われていることがわかります。対策方法についての教授を求めています。
- みんなの回答 (3)
- 専門家の回答
質問者が選んだベストアンサー
>_ftprintf(fp, _T("%s\n"), szStrRcv); //HTMLソースを.txtに書き込む >//////////この時点でszStrRcvには日本語が文字化けした内容が格納されている/////////////// 文字化けも何も、EUCやUTF-8でエンコードされたページは「EUCやUTF-8のまま」送られて来るので、そのまま表示しても文字化けしてて当たり前。 ちゃんと表示したいなら、何のコードで送られて来たか見て、自分で「EUC⇒Shift_JIS」や「UTF-8⇒Shift_JIS」に変換してあげないとならない。 あと _ftprintf(fp, _T("%s\n"), szStrRcv); はやってはダメ。 1回の受信は「多バイト文字の、文字の途中」で途切れる可能性があるので、勝手に改行を足してはいけない。 例えば、漢字の「亜」は、UTF-8で「E4 BA 9C」の3バイトだが、1回のrecvで「E4 BA」までしか来ず、次のrecvで続きの「9C … …」が来る事もある。 それを _ftprintf(fp, _T("%s\n"), szStrRcv); などと「バカな事」をしてしまうと、受信テキストは「E4 BA 改行 9C」となって、漢字の「亜」の途中に改行コードを入れてしまう。 これでは「文字化けして当たり前」だろう。 てゆか、Shift_JISでも「亜」は「88 9F」の2バイトなんだから、勝手に改行を足してたら「88 改行 9F」って感じで、文字化けしてる筈。今まで文字化けしてたのに気が付かなかっただけで。
その他の回答 (2)
- chie65536(@chie65535)
- ベストアンサー率44% (8755/19867)
もう1つ。 >HTMLソースを.txtに書き込む もし、UTF-8のコードのまま.txtに保存し、それをメモ帳で開いて正しく表示したいのなら、ファイルの先頭に「Byte Order Mark(BOM)」が無いといけない。 マイクロソフトの仕様では、UTF-8で保存されたテキストファイルの先頭には「EF BB BF」がある事になっている。 なので、ファイルの先頭にこの3バイトが無いと、メモ帳で開いた瞬間にUTF-8とは認識されず「文字がグチャグチャ」に文字化ける。 なお、メモ帳はEUCに対応してないので、EUCは必ず文字化ける。
- i-kujou
- ベストアンサー率50% (13/26)
1.文字化けはどこで確認しましたか? 単純にEUCやUTF-8を認識できないプログラムで見ているだけではないですか? VisualStudioのウォッチ画面などではShift-JIS以外の文字列を表示することはできないはずです。 2.全てのデータを受信していますか? recvでは要求ファイルの全サイズを一度に読み込むわけではありません。 通信環境により、例えば10kのファイルだったとしても1バイトしか読み込まない可能性もありえます。 以下のようにやるのが定番だと思います。 char buf[10*1024] = {0}; // 十分なサイズを用意しておく事 int offset = 0; int r = 1 while(r > 0) { // ネットワークからデータを読み込む。 // 返り値が正の数だったら、まだデータが残っている可能性がある // 0だったら全てのデータを読み込んでサーバから切断された // 負数だったらエラーが発生した r = recv(s, &buf[offset], sizeof(buf)-offset-1, 0); }
お礼
わかりました。 貴方様の意見を参考にもう少し自分で調べてみます。 ご教授ありがとうございました。
お礼
わかりました。 貴方様の意見を参考にもう少し自分で調べてみます。 現段階でなんとか文字列をANSIに変換してtxtに保存できるようになりました。 ご教授ありがとうございました。