こんにちはゲストさん。会員登録(無料)して質問・回答してみよう!

-広告-

解決済みの質問

VisualStudioの文字コードについて

現在、WindowsとLinux(Unix)でソケット通信を行い、文字のやり取りをするプログラムを作成しています。
ソースコードやコンパイルの環境は、
Windows側(Windows7):C言語(Windowsプログラミング)、VisualStudio2013でビルド&実行
Linux側:C++、g++(Cygwinを使用)
です。

Windows側のソースコードがShift-JIS、Linux側がUTF-8であり、このままだと文字化けしてしまうため、Windows側のソースコードをUTF-8に変更(VisualStudioでソースコードを保存するときに「エンコード付きで保存」を使用)して再度ビルド、実行を行ったのですが、やはり文字化けしてしまいます。

ソースコードの文字コードを変更しただけでは不十分なのでしょうか?
原因があまりよく分からず困っています。
もし何か分かることがあれば教えていただきたいです、よろしくお願いします。

(もしかしたらカテゴリ違いかもしれません、申し訳ありません)

投稿日時 - 2015-10-29 08:56:38

QNo.9071614

困ってます

質問者が選んだベストアンサー

http://sayahamitt.net/utf8%E3%81%AAstring%E5%85%A5%E3%82%8C%E3%81%9F%E3%82%89shiftjis%E3%81%AAstring%E5%87%BA%E3%81%A6%E3%81%8F%E3%82%8B%E9%96%A2%E6%95%B0%E4%BD%9C%E3%81%A3%E3%81%9F/

後は通信時のエンディアン変換ですかね。
2バイト文字だとエンディアン変換しないとやられるかも。
でもLinux側のCPUもIntelなら大丈夫な気がしますけど。

通信する際はビックエンディアンにしましょうという事なので念の為、
http://wisdom.sakura.ne.jp/system/winapi/winsock/winSock4.html

投稿日時 - 2015-11-03 06:03:09

お礼

回答ありがとうございます。
お返事が遅くなってしまい、申し訳ありません。

教えていただいたサイトを参考にし、受信したものをShift-JISに変換して表示するようにしたのですが、終端記号が入っていないためか、文字の末尾に????や||などのごみが入ってしまっています。
一応受信した時点で終端記号'\0'を入れ、Shift-JISに変換してからも終端記号'\0'を入れるようにしたのですが、うまくいっていないようです。
多分Shift-JISに変換した後に終端記号を入れる操作の方がおかしいのだと思いますが、どう直せばよいのか分からず困っています。
もし何か分かりましたら教えていただけると幸いです。よろしくお願いします。

参考までに、受信後の処理部分のプログラムを掲載します。

char buf[MAX_MESSAGE]; // 受信バッファ
int length_unicode, length_sjis;
int mtow_written, wtom_written;
UINT codepage = CP_UTF8;

nRcv = recv(ns_adda, &buf, MAX_MESSAGE, 0);
if (nRcv > 0) {
//受信文字列の末尾に'\0'を追加
buf[nRcv] = '\0';

//ワイド文字(Unicode)に変換した場合の文字列長を調べる
length_unicode = MultiByteToWideChar(codepage, 0, buf, strlen(buf), NULL, 0);
//文字列長の分だけバッファを確保
wchar_t *ws = (wchar_t *)calloc(length_unicode, sizeof(wchar_t));
//UTF-8からワイド文字に変換
mtow_written = MultiByteToWideChar(codepage, 0, buf, strlen(buf), ws, length_unicode);
if (mtow_written == 0){
//エラー処理
MessageBeep(MB_ICONEXCLAMATION);
MessageBox(hWnd, TEXT("utf-8からUnicodeへの変換に失敗しました"), szAppName,
MB_ICONEXCLAMATION | MB_OK);
return TRUE;
}

length_sjis = WideCharToMultiByte(932, 0, ws, wcslen(ws), NULL, 0, NULL, NULL);

char *ms = (char *)calloc(length_sjis + 1, sizeof(char));
// ワイド文字からマルチバイト文字に変換
wtom_written = WideCharToMultiByte(932, 0, ws, wcslen(ws), ms, length_sjis, NULL, NULL);
if (wtom_written == 0){
//エラー処理
MessageBeep(MB_ICONEXCLAMATION);
MessageBox(hWnd, TEXT("Unicodeからsjisへの変換に失敗しました"), szAppName,
MB_ICONEXCLAMATION | MB_OK);
return TRUE;
}
//終端文字を追加(ここがおかしい?)
ms[wtom_written] = '\0';
//認識結果をメッセージボックスで表示(終端記号が入っていないため末尾にごみが入る)
MessageBox(hWnd, ms, TEXT("受信結果"), MB_OK);
}

投稿日時 - 2015-11-12 20:30:00

このQ&Aは役に立ちましたか?

0人が「このQ&Aが役に立った」と投票しています

-広告-
-広告-

回答(3)

ANo.3

http://proger.blog10.fc2.com/blog-entry-67.html
マルチバイト文字列の終端文字は"\0\0"みたいだよ。
一個だと終端と思われないっぽい。

投稿日時 - 2015-11-12 21:35:41

お礼

回答ありがとうございます。

>マルチバイト文字列の終端文字は"\0\0"みたいだよ。
>一個だと終端と思われないっぽい。
そうなんですね、知らなかったです・・・。

教えていただいたことを踏まえて、MultiByteToWideCharの第三引数に+1したところ、正しく動作しました。
あとは送受信の際のバイトオーダーの変換についてですが、こちらについても少し分からないところがあるのでまた新しく質問をしようと思います。

ありがとうございました!

投稿日時 - 2015-11-13 19:15:00

ANo.1

windowsでの入力/表示はshift-jis、linuxでの入力/表示はutf-8なので、マルチバイトの文字をやりとりするのであるのでしたらプログラムの中でそれぞれの文字エンコードに変換してあげる必要があります。

投稿日時 - 2015-10-29 11:42:24

お礼

回答ありがとうございます。

質問を投稿してから、色々と自分でも調べてみたところ、
こちらのサイト【http://ameblo.jp/tomisams/entry-11254343403.html】を参考にし、Windows側のプログラムの最初に
#pragma execution_character_set("utf-8")
をつけると、Linux側で受信した文字が文字化けせず正しく表示されるようになりました。

また、hoge1229さんがおっしゃるように、受信した文字列がwindows側でshift-jisで表示されてしまっているため、utf-8で受信したものをshift-jisに変換しなければならないのですが、その方法がいまいち分かりません。(iconvは使えないですよね・・・?)
もし何かご存じでしたら、教えていただきたいです。お願いいたします。

投稿日時 - 2015-10-29 17:50:44

-広告-
-広告-
-広告-
-広告-