中国語(GB)コートのUTF-8変換について – プログラミング – Home

中国語(GB)コートのUTF-8変換に...
 
通知
すべてクリア

[解決済] 中国語(GB)コートのUTF-8変換について

固定ページ 1 / 2

やす
 やす
(@やす)
ゲスト
結合: 20年前
投稿: 27
Topic starter  

GB(中国語)で作成したファイルを読み込み、UTF-8に変換するプログラムを
作成しています。
読み込むファイルの内容は「你你」が入っています。

下記プログラムを実行すると、ctestbuffには下記で設定されます。
EF BE 84 E7 BF 94 E3 83 BB 00

このファイルをひでまるでUTF-8で保存すると下記で設定されます。
E4 BD A0 E4 BD A0 0D 0A,

想定では同値となるはずなのですが、どこか設定が悪いのでしょうか。

尚、中国語なので、初めにsetlocale(LC_ALL, chinese);としています。

環境VC2003
WindowsXP(日本語OS) 日本語OSがまずいのでしょうか?

void Test2(){

char ctestbuff[256];
CStringA cRet;
CStringA cReadTestA;
CStringW cReadTestW;

setlocale(LC_ALL, zh);

// ICONT別IO情報CSVファイルオープン
FILE *fpp = fopen( D:\\temp\\gb.txt, r );
if( fpp == NULL ){
return ;
}

while(1){
// HIM用IO情報CSVデータを1行読み取り
fgets( ctestbuff, sizeof( ctestbuff ), fpp );
if( feof( fpp ) ){
break;
}
cReadTestA = ctestbuff;
cReadTestW = cReadTestA;
cRet = UTF16toUTF8(cReadTestW);
strcpy(ctestbuff,cRet);
}

fclose(fpp);
}

CStringA UTF16toUTF8(const CStringW& utf16)
{
CStringA utf8;
int len = WideCharToMultiByte(CP_UTF8, 0, utf16, -1, NULL, 0, 0, 0);
if (len>1)
{
char *ptr = utf8.GetBuffer(len-1);
if (ptr) WideCharToMultiByte(CP_UTF8, 0, utf16, -1, ptr, len, 0, 0);
utf8.ReleaseBuffer();
}
return utf8;
}


引用未解決
トピックタグ
YuO
 YuO
(@YuO)
ゲスト
結合: 16年前
投稿: 4
 

CStringAとCStringWの変換規則って定義されていましたっけ。
コードを流し読みした限りだと,あくまでCP_THREAD_ACPを使ってAPIによる変換をしてい
るようにしか見えませんが。
つまり,setlocaleは全くの無駄のようです。

・fgetsをfgetwsに変更して,ワイド文字列を読み込む
・fgetsで取得した文字列を,該当コードページ (936?) を使って,MutliByteToWideChar
を自分で発行する
といった方法を試してみてはどうでしょうか。


返信引用
やす
 やす
(@やす)
ゲスト
結合: 20年前
投稿: 27
Topic starter  

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

CStringAとCStringWに関してはMFCが自動で変換してくれるようです。
(SHIFTJISとUNICODEではうまくいっていますが、これに関しては使用しなくてもかまい
ません。)

fgetwsに関しては、処理自体は既存の処理に手を加えるので、fgetsを使用する必要があ
ります。

fgetsでバイトコードは「C4,E3,C4,E3」と正しく読めているので、
これを画面上に「你你」と表示する方法はあるのでしょうか?


返信引用
やす
 やす
(@やす)
ゲスト
結合: 20年前
投稿: 27
Topic starter  

上記はUTF-8で設定後、そのデータを画面上に表示するのが目的です、そもそもGBのデー
タを画面上に表示できるかを確認しようとしています。


返信引用
やす
 やす
(@やす)
ゲスト
結合: 20年前
投稿: 27
Topic starter  

ファイルから読み込んだ文字「にーはおの1つ目の文字を2つ入れてます」をSIMHEIフ
ォントにしたダイアログへの表示はうまくいきました。
やはりWideCharToMultiByte関数のUTF-8への変換がうまくいかないみたいです。


返信引用
PATIO
(@patio)
Famed Member
結合: 3年前
投稿: 2660
 

単純にGBコードの文字を表示したいだけなら
GBに対応したフォントを使って文字を描画すれば良いだけではないかと
思います。読み込めたコードが正しいかを見たいだけならと言う話です。
エディットボックスやスタティックコントロールなら対応するフォントを
コントロールに設定して文字列を設定すれば良いような気がします。

それともやりたい事がこれとは違う事なんでしょうか。


返信引用
PATIO
(@patio)
Famed Member
結合: 3年前
投稿: 2660
 

あらら、入れ違いになってしまった。

そもそもCStringで変換しているGBからunicodeへの変換は
うまくいっているのでしょうか?
そこの確認をしないとWideCharToMultiByteでの変換の話は
出来ないと思いますけれど。


返信引用
aetos
(@aetos)
Noble Member
結合: 5年前
投稿: 1480
 

> cReadTestA = ctestbuff;
> cReadTestW = cReadTestA;

この処理は何のために入れてるんですか?
UTF16toUTF8 に直接 ctestbuff を渡せばいいような気がするんですが。


返信引用
aetos
(@aetos)
Noble Member
結合: 5年前
投稿: 1480
 

あ、ごめん。勘違い。元が UTF-16 じゃないのか。
なら、CString を使わず、MultiByteToWideChar で UTF-16 にすべきだと思います。


返信引用
やす
 やす
(@やす)
ゲスト
結合: 20年前
投稿: 27
Topic starter  

MultiByteToWideChar及びWideCharToMultiByteで再度確認しましたが、
結果は変わりませんでした。
実行環境は、「マルチバイト文字セットを使用する」で実行しています。
又、setlocaleは必要なのでしょうか?とりあえず中国で設定しています。

char ctestbuff[8];
char cBuffUtf8[16];
wchar_t cBuffUtf16[16];

setlocale(LC_ALL, zh-cn); // これは必要でしょうか?

// ICONT別IO情報CSVファイルオープン
FILE *fpp = fopen( D:\\temp\\gb.txt, r );
if( fpp == NULL ){
return ;
}

while(1){
fgets( ctestbuff, sizeof( ctestbuff ), fpp );
if( feof( fpp ) ){
break;
}

//画面上に文字を表示 期待通りの文字が出力される
//取得文字:C4 E3 0A (にーはおのにーの一文字)
m_EdTest1.SetWindowText(ctestbuff);

//UTF-16変換
::MultiByteToWideChar(CP_ACP, 0, ctestbuff,strlen(ctestbuff),
cBuffUtf16,sizeof(cBuffUtf16));

//UTF-8変換
WideCharToMultiByte(CP_UTF8, 0, cBuffUtf16, -1, cBuffUtf8,
sizeof(cBuffUtf8), 0, 0);

//UTF-16変換
::MultiByteToWideChar(CP_UTF8, 0, cBuffUtf8,strlen(cBuffUtf8),
BuffUtf16,sizeof(cBuffUtf16));

//変換
WideCharToMultiByte(CP_ACP, 0, cBuffUtf16, -1, ctestbuff,
sizeof(ctestbuff), 0, 0);

//画面上に文字を表示 文字化け!!
m_Ed2.SetWindowText(ctestbuff);

}

fclose(fpp);


返信引用
subaru
 subaru
(@subaru)
ゲスト
結合: 19年前
投稿: 381
 

元はやっぱりUTF-16っぽいよ。
これなら意味わかりますか?

WCHAR wstr[] = {20320, 20320, 0};
cReadTestW = wstr;
cRet = UTF16toUTF8(cReadTestW);
strcpy(ctestbuff,cRet);


返信引用
subaru
 subaru
(@subaru)
ゲスト
結合: 19年前
投稿: 381
 

>fgetsでバイトコードは「C4,E3,C4,E3」と正しく読めているので、

あ、元はこっちか。
ごめん。勘違いorz


返信引用
aetos
(@aetos)
Noble Member
結合: 5年前
投稿: 1480
 

> //UTF-16変換
> ::MultiByteToWideChar(CP_ACP, 0, ctestbuff,strlen(ctestbuff),
> cBuffUtf16,sizeof(cBuffUtf16));

この第一引数は 936 でしょう。

で、それはそれとして、そもそも、UTF-8 を直接表示したいのはどうしてですか?
UTF-16 に変換して表示するのでは、何か都合が悪いのですか?
UTF-16 で表示するのなら、適切なフォントを選んだ上で TextOutW なり何なりすればい
いのですが、UTF-8 の直接表示は方法がわかりません。

> ごめん。勘違いorz

うん、俺も同じ勘違いw


返信引用
やす
 やす
(@やす)
ゲスト
結合: 20年前
投稿: 27
Topic starter  

作成中のアプリはWindowsでUTF-8としてデータを作成し、LINUXでそのデータを使用しま
す。
ですので、画面上でUTF-16として中国語を扱い、データの保存はUTF-8に変換ということ
を実現したいのです。
日本語と中国語をオプションで切り分けており、日本語はうまくいっているのですが、
中国語は文字化けしてしまう状況です。


返信引用
aetos
(@aetos)
Noble Member
結合: 5年前
投稿: 1480
 

えっと、俺また勘違いした?

例えば、TextOut の引数に、UTF-8 でエンコードされた char 配列を渡して表示した
い、ということを意図していますか?


返信引用
固定ページ 1 / 2

返信する

投稿者名

投稿者メールアドレス

タイトル *

プレビュー 0リビジョン 保存しました
共有:
タイトルとURLをコピーしました