
VC++2010, MFCです。
参考ページ(↓)でできそうだったのですが、
http://www.sutosoft.com/oldroom/devdiary/2002050 …
UTF-8からShift_JISにしたいのは、メディアプレーヤーで作られた wpl ファイルも扱いたいからです。
具体的にいうと、ファイル一覧に プレイリストがあった場合、展開してメディアプレイヤーで開いて、再生後 【m3u ファイル】に(コーディングで)アウトプットするのが目的です。 ShiftJISに変換して、いったんファイルに出力してから、再度読込処理を行ってもかまいません。
BOOL C○○Dlg::UTF8ToShiftJIS(const CString& src, CString* dest)
{
int sizeOfString = (src.GetLength() + 1);
LPWSTR lpsz = new WCHAR[sizeOfString];
//LPSTR lpsz = new char[ sizeOfString ];
_tcscpy_s(lpsz, sizeOfString, src);
//strcpy_s(lpsz,sizeOfString, src);
//delete[] lpsz
//http://rararahp.cool.ne.jp/cgi-bin/lng/vc/vclng. …
//char* orig = "Hello, World";
char* nstring;
nstring = new char[sizeOfString];
strcpy_s(nstring,sizeOfString, (LPCSTR)(lpsz));
// ●UTF8からUnicodeに変換した場合の長さを求める。●
//http://msdn.microsoft.com/ja-jp/library/cc448053 …
//const_cast<LPTSTR>(static_cast<LPCTSTR>(str)
int iWideLength = ::MultiByteToWideChar(CP_UTF8, 0,【1】nstring, src.GetLength(), NULL, 0);
if (iWideLength == 0)return FALSE;
LPWSTR lpWideString = new WCHAR[iWideLength];
int iLength;
if (
// ●UTF8からUnicodeに変換する。●
(::MultiByteToWideChar(CP_UTF8, 0, 【2】nstring, src.GetLength(), lpWideString, iWideLength) == 0)
// ●UnicodeからShift_JISに変換した場合の長さを求める。●
|| ((iLength = ::WideCharToMultiByte(CP_ACP, 0, lpWideString, iWideLength, NULL, 0, NULL, NULL)) == 0)
// ●UnicodeからShift_JISに変換する。●
//http://msdn.microsoft.com/ja-jp/library/cc448089 …
|| (::WideCharToMultiByte(CP_ACP, 0, lpWideString, iWideLength, 【3】(LPSTR)dest->GetBuffer(iLength), iLength, NULL, NULL) == 0)){
// ●変換に失敗●
delete lpWideString;
return FALSE;
}
// ●変換に成功●
delete lpWideString;
dest->ReleaseBuffer();
return TRUE;
}
・・・という風に少し修正をして、次のソースで呼び出しています。
CString src;
CFile file;
if (file.Open(FilePath, CFile::modeRead)){
DWORD iLength = file.GetLength();
//CString src;
file.Read(src.GetBuffer(iLength), iLength);
file.Close();
src.ReleaseBuffer(iLength);
CString dest;
if (UTF8ToShiftJIS(src, &dest) ==TRUE){
MessageBox (dest);
}
// ●この時点で、destにShift_JISに変換された文字列が格納されている。
}
以下(↓)を参考に、【1】~【3】の部分で、他のパターンもキャストしてみたのですが・・・
/* http://d.hatena.ne.jp/shikaku/20090519/p3
■[CPP][VC]LPCSTRなどのVC++の紛らわしい定義の意味
一見正体不明のVC++オリジナル定義。よーくみれば違いが分かる。名前意味
LP*(ポインタ)
Cconst
TSTRTCHAR(char)
STRchar
WSTRWCHAR(ユニコード用:2byte)
ゆえに定義正体
LPSTRchar*
LPCSTRconst char*
LPTSTRTCHAR*
LPCTSTRconst TCHAR*
LPWSTRWCHAR*
LPCWSTRconst WCHAR*
となる。+/
できるだけスマートに記述したいです。エクセル版を作っていたときは、CreateObject("ADODB.Stream")を使っていたみたいです。ただ、VC++でどう書けばいいか、分かりませんυ
UTF8→UTF16→ShiftJIS ←これは、あまり、使いたくない 変換 です。
後は、これも参考になりそうですが、 http://www.softist.com/programming/sjis-utf8/sji …
bufUTF8を何型でどこで宣言すればいいのか?分かりません。
これも(↓)はてなです。
http://www.s-cradle.com/developer/sophiaframewor …
何回も試しましたが、TRUEが返ってきても、変換前と変換後をMessageBoxで比べてみても、変わりがなく、漢字や記号の羅列でしかありません。どうか教えてください。
No.3ベストアンサー
- 回答日時:
CString型は、プロジェクトの文字セットの設定の影響を受けます。
・”マルチバイト文字セットを使用する”の場合:CStringA
・”Unicode 文字セットを使用する”の場合:CStringW
異なる文字コードを扱う必要のあるプログラムでは、CString型ではなく、
CStringA, CStringW を使い分ける必要があります。
UTF-8 を格納する適切なCString型はありませんので、
・バイナリデータとして扱う(通常はこちら)
・CStringA に格納する(次善の策)
ぐらいかと思います。
残念ながら元のコードでは、プロジェクトがUnicode文字セットの設定の場合には、
動作する可能性がありません。
<コード例>
BOOL C○○Dlg::UTF8ToShiftJIS(const CStringA& src, CStringA* dest)
{
// UTF-8 -> Unicode
//
int iWideLength = ::MultiByteToWideChar(CP_UTF8, 0, src, -1, NULL, 0);
if (iWideLength == 0) return FALSE;
CStringW temp;
int iLength = ::MultiByteToWideChar(CP_UTF8, 0, src, -1, temp.GetBuffer(iWideLength), iWideLength);
temp.ReleaseBuffer();
if (iLength == 0) return FALSE;
// Unicode -> S-JIS は、CString 標準の変換を使用する。
// 何か問題がある場合は、::WideCharToMultiByte の使用を検討する。
//
*dest = temp;
return TRUE;
}
CStringA src;
CFile file;
if (file.Open(FilePath, CFile::modeRead)) {
DWORD iLength = file.GetLength();
file.Read(src.GetBuffer(iLength), iLength);
file.Close();
src.ReleaseBuffer(iLength);
// ファイルから読み込んでるが、UTF-8 の BOM(EF, BB, BF)の扱いは大丈夫か?
//
static const BYTE utf8_bom[3] = { 0xEF, 0xBB, 0xBF };
if (::strncmp(src, reinterpret_cast<const char*>(utf8_bom), 3) == 0) {
src.Delete(0, 3);
}
CStringA dest;
if (UTF8ToShiftJIS(src, &dest)) {
// 文字コードが S-JIS なので、ANSIバージョンを明示的に使用する必要がある
// (MessageBox ではなくて、MessageBoxA)
//
::MessageBoxA(m_hWnd, dest, "てすと", MB_OK);
}
}
この回答への補足
凄いです!こんなにスマートにかけるなんて、ご回答ありがとうございました m(_ _)m
後は、もう少し検証してから(土曜日あたりに)締め切らせてもらいます。
エクセルの方でも、バイナリ形式で処理するサンプルがありますので、そこら変ももう一度見てみます。
今回は全てコーディングしてもらいましたが、VC初心者を免罪符にしないようにしたいですが、正直、難しいです。。。(ΘoΘ;)
では。
分かりやすい説明と完全に動くソースコードまで、ありがとうございました!
うまく行きました。
(メディアプレイヤーのパラメータに、大量のファイルのフルパスを一個一個与えて再生しようとすると、全然再生されない(遅い?)ようです。パラメータの長さに限りがあるのでしょうか?)
(一度、プレイリスト(m3u)ファイルに出力して、そのファイルのフルパスをメディアプレイヤーのパラメータに与えると、早く処理されるようです。)
では、締め切らせていただきますね。m(_ _)m
No.2
- 回答日時:
下記の回答は誤りです。
申し訳ありません。--------------------
UTF8->ShiftJISは、
WideCharToMultiByte(CP_UTF8, .....);
で、UNICODEを経由しなくても、1回で変換できると思います。
第1引数をCP_UTF8にしてください。
この回答への補足
回答ありがとうございます。
誤り、分かりました。
今は、心が折れて(?)しまったので、水曜日以降、もうちょっと試行錯誤してみようと思います。
極力、コード表とにらめっこでコーディングする事をさけ(←バグを排除するためにです)、VCに用意された命令で、実現したいです。
でも検索したら、文字コードを変換するフリーソフトが沢山ヒットしました。
簡単に作れるなら、それらのツールは不要なわけで・・・と、ここで質問した事との矛盾は感じています。(だから、しばらく回答が0だったのかも知れませんねυ)
質問にあるとおり、 http://www.sutosoft.com/oldroom/devdiary/2002050 … から、コードをコピーしたら、引数の所で、型が合わないというエラーがでたので、型だけ無理やりあわせました。
(つじつま合わせの型変換は意味ないのでしょうか?)
値渡しか、参照渡しか、の意味は分かりますが、正確な表記方法は分からないかもしれません。
ちなみに、言い忘れましたが、プロジェクトの設定は、ちゃんとユニコード対応にしています。
どなたからヒントだけでもいいので、教えていただけると嬉しいです。
ではでは。
No.1
- 回答日時:
UTF8->ShiftJISは、
WideCharToMultiByte(CP_UTF8, .....);
で、UNICODEを経由しなくても、1回で変換できると思います。
第1引数をCP_UTF8にしてください。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
このQ&Aを見た人はこんなQ&Aも見ています
関連するカテゴリからQ&Aを探す
おすすめ情報
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
家電製品の電力周波数を変える機械
-
FortranをC++(VC++)へ変換
-
逆コンパイルと逆アセンブルの...
-
.sb3のファイルを.sb2に変換す...
-
VB6で16進のXOR演算
-
VB 6 を VS 2012に変換するには?
-
シーケンサのCPUはニーモニック...
-
UTF8→ShiftJISに変換したいです!
-
ASP.NET SJIS→UTF-8文字コード...
-
C#でのpngからbmpへの変換について
-
10進数をBCDに変換する方法
-
アセンブラ言語の数字を数値に...
-
HRESULTの代替となる型
-
N88BASICのバイナリデータをテ...
-
緯度、経度の 10進法と 60進法...
-
gmtime()とlocaltime()は
-
Macターミナルで実行中のプログ...
-
powershell を使いカレントディ...
-
TCP/IP通信時のサーバーからの受信
-
Windows上で、シグナル(SIGTERM...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
家電製品の電力周波数を変える機械
-
逆コンパイルと逆アセンブルの...
-
エクセルVBAの自動変換機能?
-
10進数をBCDに変換する方法
-
VB6からVB2010への変換について
-
緯度、経度の 10進法と 60進法...
-
分を時間に変換するプログラム
-
C#で漢字→ローマ字を変換
-
なぜ通信には16進数文字列が使...
-
vb.netの型変換について
-
正規表現でルビを小書きに変換...
-
マンセル⇔XYZ,RGB変換式或いは...
-
C#で漢数字をアラビア数字に変...
-
VB6から.NETへアップグレード時...
-
php
-
VB 6 を VS 2012に変換するには?
-
3のつく数字と3の倍数のみを表...
-
C++からCへのソース変換について
-
エクセルのvbaで検索ボタンを作る
-
tex 郵便記号のだしかた
おすすめ情報