dポイントプレゼントキャンペーン実施中!

DELPHI3で作ったプログラムの中で
インターネットからDownloadした文字コードUTF-8のHTML文のTEXTファイルを
下記 function UTF82Sjisで、文字コードUTF-8からShift-JISへ変換して表示しています。

このプログラムをDELPHI3からDelphi 10.2 スターターエディションに
移植しているのですが、function UTF82SjisはDelphi 10.2では機能しません。

代わりとしてDelphi 10.2の UTF8ToString(utf8) を使って
MSG:= AnsiString(UTF8ToString(OrgnText)) でShift-JISへ変換をしているのですが
漢字や記号は正しく変換されるものもありますが可成りは変換エラーとなります。

どこを直せべ良いのでしょうか?
或いは、DELPHI3の下記function UTF82SjisをDelphi 10.2用にどう直せば良いのでしょうか?

文字コード及び文字コード変換は詳しくないので宜しくお願いします。


参考:DELPHI3での変換

http://m-and-i.my.coocan.jp/tips/utftosjis.htm  UTF-8とShift-JIS文字コード自力変換(2004/4/24)(このHPの著者の方が分からなくて申し訳ないですが)の記事にあった function UTF82Sjis のプログラムを利用させてもらっています。

// UTF-8をSJISに変換する
function UTF82Sjis(UTFStr: string): string;
var
usc2, uc: PChar;
pwc: PWideChar;
len: integer;
un: WORD;
begin
Result := '';
len := Length(UTFStr);
// 文字列の終わりを検出するために番兵4人を立てる
uc := PChar(UTFStr + #0#0#0#0);
// 安全を見て4倍のメモリを確保
usc2 := AllocMem(len * 4);
// usc2はポインタとして使うのでpwcに先頭アドレスを保存
pwc := PWideChar(usc2);
try
while uc^ <> #0 do
begin
// ASCII
if uc^ in [#0..#$7F] then
begin
usc2^ := uc^;
(usc2+1)^ := #0;
Inc(usc2, 2);
Inc(uc);
// 2byte文字その1
end else if uc^ in [#$C0.. #$DF] then
begin
un := (Ord(uc^) and $1F) shl 6 + Ord((uc+1)^) and $3F;
usc2^ := Char(Lo(un));
(usc2+1)^ := Char(Hi(un));
Inc(usc2, 2);
Inc(uc, 2);
// 2byte文字その2
end else if uc^ in [#$E0..#$EF] then
begin
un := (Ord(uc^) and $0F) shl 12 + (Ord((uc+1)^) and $3F) shl 6
+ (Ord((uc+2)^) and $3F);
usc2^ := Char(Lo(un));
(usc2+1)^ := Char(Hi(un));
Inc(usc2, 2);
Inc(uc, 3);
// 4byte文字(USC-4のみ)
end else if uc^ in [#$F0..#$F7] then
begin
un := (Ord(uc^) and $07) shl 2 + (Ord((uc+1)^) shr 4) and $03;
usc2^ := Char(Lo(un));
(usc2+1)^ := Char(Hi(un));
Inc(usc2, 2);
Inc(uc);
un := ((Ord(uc^) shl 4) and $F0) + (Ord((uc+1)^) and $3F) shl 6
+ (Ord((uc+2)^) and $3F);
usc2^ := Char(Lo(un));
(usc2+1)^ := Char(Hi(un));
Inc(usc2, 2);
Inc(uc, 3);
end else
raise Exception.Create('UTF-8 Unknown code.');
end;
// UTFから変換したUnicodeをString型で返す。これだけでSjisになっちゃう
Result := pwc;
finally
FreeMem(pwc);
end;
end;

質問者からの補足コメント

  • ご回答ご教示有難うございます。
    各変換の画像を添付します。
    原文はYAHOOファイナンスのUTF8のHTML文TEXTファイルです。

    'OrgnText:(UTF8)'

    'UTF8ToString(OrgnText):'
    半角カタカナは変換されますが、漢字は正しく変換されるものと文字化けするものがあります。

    'Utf8ToAnsiEx(OrgnText,932):(Shift-JIS)'
    文字化けして'OrgnText:(UTF8)'の時と同一です

    或いは、System.WideStrUtils.Utf8ToAnsiExが正しく932を参照していないのでしょうか?

    プラグラムの中で
    uses  System.WideStrUtils, 
    MSG:=Utf8ToAnsiEx(OrgnText,932); と記述しただけですが、何か足りないのでしょうか?

    「[Delphi 10.2] UTF-8か」の補足画像1
    No.1の回答に寄せられた補足コメントです。 補足日時:2017/10/25 16:59
  • DelphiのBibleも言える方からご回答を頂き恐縮です。

    >そのコードがないのでは直すべき部分がアドバイスできません.

    最初の質問の下部に書いたDelphi3用の「function UTF82Sjis」プログラムをDelphi10.2用に改造できないかと質問させて貰らいました。

    >文字列をコードページ Shift-JIS として扱うには String 型ではなく AnsiString 型の変数に代入します.

    HTML文をAnsiString 型に読み込んで見ましたが、同一の文字化けが発生しました。

    >本当に Shift-JIS への変換が必要なのかを考える必要があると思います.

    目的はShift-JIS への変換したいのではなくて、UTF-8で記述されているHTMLの漢字をDelphiで読み込んで解析したいのです。

    宜しくお願い申し上げます。

    No.4の回答に寄せられた補足コメントです。 補足日時:2017/10/28 22:58
  • ご教示有難うございます。

    >[883_文字コードページとテキストファイルの保存と表示]

    目を通していましたが、よく理解できていなかったようです。

    >その元のテキストのコードページを指定するだけです.

    この指定方法が分かっていなかったです。今回例示プログラムで稼働できました。
    もう少し研究するとMASTER出来そうです。

    有難うございます。DELPHIの理解が深まりました。

    >Delphi 専門のコミュニティがあります.

    訪問するための具体的名称かURLを教えて戴けますか。

    >「文字化けします」「うまくいきません」を九官鳥のように繰り返しても何の解決にもなりません.

    申し訳ありません。反省します。
    ご忠言のほど有難うございます。ご厚意に痛み入ります。

    No.5の回答に寄せられた補足コメントです。 補足日時:2017/10/29 22:17

A 回答 (6件)

>目的はShift-JIS への変換したいのではなくて、UTF-8で記述されているHTMLの漢字を



HTML の漢字というより「テキスト」ですね.
これは一度経験してしまえばそれほど難しくありません.最初の一歩だけです.前のレスに書いた

[ Delphi が初めての方と Delphi 2007 以前からの移行]
http://mrxray.on.coocan.jp/Delphi/Others/Delphi_ …

の記事にリンクが貼ってあります.

[883_文字コードページとテキストファイルの保存と表示]
の記事をご覧ください.[参考リンク] としてあるので,既にお読みになっていたらご容赦ください.
簡単なテストコードがあればアドバイスできますが,ないので記事で確認してください.
もし,それでも理解てきない時は,Delphi 専門のコミュニティがあります.
是非利用してください.教えて goo はほとんど見ることはありませんが,コミュニティ場には頻繁に出没しています.

Delphi 2009 以降では文字列の扱いが便利で簡単になりました.
UTF-8 のテキストを表示する場合は,読み込む時 (何にどうやってが不明ですのでこの表現とさせていただきます) に,その元のテキストのコードページを指定するだけです.

くどいようですが,プログラムはコードで動作します.
ファイルを読み込んで表示するというのであれば,そのような簡単なテスト用のプログラムを作成してそのコードを掲載することです.
自分がネット上にあるコード等を試すことわ考えてみるとよいと思います.
文章だけではやれなくとも,コードがあればテストできるハズです.
こういうことは,昔から何回も言い尽くされてきたことですので,ここで書くのも恥ずかしいくらいですが.
コードがなければ始まりません.

「文字化けします」「うまくいきません」を九官鳥のように繰り返しても何の解決にもなりません.
私は具体的なコードないとアドバイスできないとレスしましたし,他の方も『確認のためのテキスト出力をどうやっているのかが不明ですが』と書いていますよ.
この回答への補足あり
    • good
    • 0

>訪問するための具体的名称かURLを教えて戴けますか。



私のサイトの以下にリンクがあります.
Google で「Delphi 掲示板」で検索しても見つかります.
インターネットはリンクで成り立っています.
リンクの記事にあるリンクを辿ればまた,新しい情報があるかも知れません.

http://mrxray.on.coocan.jp/Links.htm#Delphi_Other

>申し訳ありません。反省します。

謝る必要はありません.
単に,自分自身の問題解決が遅くなるだけです.
問題を早く解決する方法をアドバイスしただけです.文句を言っているわけではありません.

ついでにアドバイスとしておくと,このような掲示板をご覧になっている方々にはレスする権利はあります.しかし,レスする「義務」は全くありません.
そして,インターネットの向こう側は見えないということです.エスパーも存在しません.
だからこそ,コード等の具体的な情報が必要なわけです.

昔,次のような質問をメールでいただいたことがあります.
貴方ならどう反応するでしょうか ?
もし興味があれば,私のサイトの掲示板 (雑談系の掲示板) にでも書き込んでください.

《ShowMessage('終わりました'); が動作しません.表示できません.どうしてでしょうか》
    • good
    • 0
この回答へのお礼

有難うございます。
お蔭様で、UTF-8のHTML文がDelphi 10.2で読み込み解析ができました。
自作プログラム本体もこれでDelphi 10.2への移行が可能となってきました。
宜しかったらご参考までにご訪問ください。
http://www.kabuchart.com

お礼日時:2017/11/06 16:35

>どこを直せべ良いのでしょうか?



残念ながら私はエスパー (超能力者) ではないので具体的な方法は提示できません.
プログラムというのはコードを書いて,それを実行することで何かの操作をしたり,結果を出すものです.
そのコードがないのでは直すべき部分がアドバイスできません.

以下は参考なるかも知れない記事です.
内容は他の方のレスの内容とほとんと変わりません.少しくどいだけです.
文字列をコードページ Shift-JIS として扱うには String 型ではなく AnsiString 型の変数に代入します.
ただし,本当に Shift-JIS への変換が必要なのかを考える必要があると思います.
これも既に他の方のレスに書いてあります.よくお読みになった方がよろしいかと.

[ Delphi が初めての方と Delphi 2007 以前からの移行]
http://mrxray.on.coocan.jp/Delphi/Others/Delphi_ …
この回答への補足あり
    • good
    • 0

確認のためのテキスト出力をどうやっているのかが不明ですが・・・



> 'OrgnText:(UTF8)'
この段階で文字コードの不整合が発生していると思われます。
ちょっと調べた感じでは現在のDelphiの文字列型変数はコードページを内蔵しているので、文字列変数のコードページが実際のエンコードと一致していれば、どのコードページの文字列でもShowMessageで正しく表示されるらしいですので。
推測ですが、インターネットからダウンロードしたHTMLデータをOrgnTextに代入する時点で間違ったコード変換を行って壊していると思います。日本語Windowsのデフォルト文字コードはCP932(SJIS)なので、OrgnTextに代入する段階でSJIS=>UTF-8変換が発生している可能性があります。
# UTF-8文字列をSJISとみなして変換するので当然に壊れます

参考にしたサイト
# http://ht-deko.com/tech014.html
    • good
    • 0
この回答へのお礼

有難うございます。
お蔭様で、UTF-8のHTML文がDelphi 10.2で読み込み解析ができました。
自作プログラム本体もこれでDelphi 10.2への移行が可能となってきました。
宜しかったらご参考までにご訪問ください。
http://www.kabuchart.com

お礼日時:2017/11/06 16:38

Delphiは全く知りませんが、


「Unicodeにしてしまえば、あとはString型に代入するだけでDelphiが自動的にSJISにしてくれる」
というDelphi3の仕様が10で変わったために使えなくなったということなのでしょうから、その関数を直すのは不可能でしょう。
    • good
    • 0
この回答へのお礼

有難うございます。
お蔭様で、UTF-8のHTML文がDelphi 10.2で読み込み解析ができました。
自作プログラム本体もこれでDelphi 10.2への移行が可能となってきました。
宜しかったらご参考までにご訪問ください。
http://www.kabuchart.com

お礼日時:2017/11/06 16:38

Delphiは良く分かりませんが、AnsiStringでShift-JISが正しく扱えるの?


ちょっとネットで検索した感じだとDelphiにおける文字列の扱いはかなり変化していて現在ではstringはUnicode文字列になっているようなので、表示するならわざわざAnsiStringに変換せずにUTF8ToString(utf8)で返ってくるstringをそのまま表示すれば良いのでは?
どうしてもShift-JISを扱う必要があるなら、System.WideStrUtils.Utf8ToAnsiExとか、コードページを直接指定できるAPIを使って932(Shift-JISのコードページ)で呼び出してみるとか。絶対うまくいくとは言えないけど。
この回答への補足あり
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!