WideCharが半角か全角か判断したい

解決


Fusa  2006-05-13 05:26:26  No: 21502

こんにちは。

Unicode文字(WideChar)が半角で描かれるのか全角で描かれるのかを区分けしたくて
以下のコードで取得できる
HiByte=00で区別できるかと思ったのですが

半角カタカナを読み込ませたところ
HiByteがFFでした

Unicode文字(WideChar)が半角で描かれるのか全角で描かれるのかは
HiByteが00か、FFか、で判断してよいものでしょうか?

教えてください。よろしくお願いします。

調査のためのコードです。

procedure TForm1.Button1Click(Sender: TObject);
var
  swork: WideString;
  msg: AnsiString;
  i: Integer;
  Buffer: Char;
begin
  // WideStringの内容をチェック
  swork := 'ABCあいうアイウエオアイウエオ';
  msg := '元の文字列=' + swork + #13#10;

  for i := 1 to Length(swork) do
  begin
    Buffer := Char(HiByte(word(swork[i])));
    msg := msg + IntToHex(Ord(Buffer), 2) + ' ';
    Buffer := Char(LoByte(word(swork[i])));
    msg := msg + IntToHex(Ord(Buffer), 2) + ' ';
  end;
  ShowMessage(msg);
end;


Fusa  2006-05-13 05:33:04  No: 21503

半角カタカナが消えてしまっていますが、
二つめのアイウエオは半角カタカナです。

HiByteなどでチェックしたいわけではなく
他にもよい判断方法ご存じでしたら
教えてください。


ママん  2006-05-13 06:24:16  No: 21504

目的によると思いますが、
1.半角、全角が含まれているかどうか
2.半角 - 全角  変換が行いたい
のであればLCMapStringWなんていうWindowsAPIがあります。


えーと  2006-05-13 06:40:41  No: 21505

string に代入して長さ見てみたらいいんじゃないでしょうか


Fusa  2006-05-13 07:25:40  No: 21506

お返事ありがとうございます。

目的は、WideStringでの半角80桁折り返し処理、ですので(もちろん80は可変)
文字列を頭から検索していって80桁目になったかどうかを調べるために
WideCharの1文字が半角か全角かを知りたいのです。
LCMapStringWではちょっと処理が遠い気がします。

stringに代入、、、うーん、高速化という意味でもUnicodeのみの処理という
意味でも、少し避けたいところです。

わがままですいません。


風来坊  2006-05-13 11:39:15  No: 21507

GetCharWidth32W か GetTextExtentPoint32W で調べる。
でも GetCharWidth32W は正しい値を取得できない場合がある。
Unicodeの場合、固定幅フォントでも 半角:全角=1:2とはかぎらないのが困りものですが…
半角より幅が広いけど全角より狭い文字があったり、全角よりも幅が広い文字があったり…

単純にACSII文字と半角カナが知りたいのであれば、
case Ord(wc) of // var wc: WideChar;
  $20..$7F, $FF61..$FF9F:
    // 処理
end;
で、判断できます。
$20..$7F, $FF61..$FF9F についてはちゃんと調べていませんが…

ちなみにHIBYTEの$FFには全角アルファベットも含まれていますよ。


風来坊  2006-05-13 11:40:37  No: 21508

ACSII -> ASCII の間違い。


Fusa  2006-05-13 22:01:30  No: 21509

なるほど、そういうアプローチもあるわけですね。
文字幅を微妙なところまで考え出すと非常に複雑ですね.....

大変勉強になりました。ありがとうございます。

ヒントいただきましていろいろ探して

Unicode対応 文字コード表
http://ash.jp/code/unitbl1.htm

を参考にみて、
次の関数を作って望みのものができました。

Delphiでは
『\』の扱いは参考のページとは違って $005C として表現されるようです。
『~』は参考ページ通り $203E でした。

type TWideCharByteLength = (wcblSingle, wcblMulti);

function WideCharByteLength(source: WideChar): TWideCharByteLength;
var
  Buffer: word;
begin
  Buffer := Ord(source);
  case Buffer of
    $0020..$007F, $203E, $FF61..$FF9F:
    begin
      Result := wcblSingle;
    end;
    else
    begin
      Result := wcblMulti;
    end;
  end;
end;

ファーストテストコードは次のようになります。
(カタカナや記号は全部半角)

procedure Check(A, B: Variant); overload;
begin
  if not(A = B ) then
  begin
    Assert(False, 'エラーです');
  end;
end;

procedure testWideCharByteLength;
begin
  Check(wcblSingle, WideCharByteLength(WideChar(WideString('a')[1])));
  Check(wcblSingle, WideCharByteLength(WideChar(WideString('g')[1])));
  Check(wcblSingle, WideCharByteLength(WideChar(WideString('z')[1])));
  Check(wcblSingle, WideCharByteLength(WideChar(WideString('A')[1])));
  Check(wcblSingle, WideCharByteLength(WideChar(WideString('G')[1])));
  Check(wcblSingle, WideCharByteLength(WideChar(WideString('Z')[1])));
  Check(wcblSingle, WideCharByteLength(WideChar(WideString('\')[1])));
  Check(wcblSingle, WideCharByteLength(WideChar(WideString('[')[1])));
  Check(wcblSingle, WideCharByteLength(WideChar(WideString(']')[1])));
  Check(wcblSingle, WideCharByteLength(WideChar(WideString('^')[1])));
  Check(wcblSingle, WideCharByteLength(WideChar(WideString('`')[1])));
  Check(wcblSingle, WideCharByteLength(WideChar(WideString('_')[1])));
  Check(wcblSingle, WideCharByteLength(WideChar(WideString('~')[1])));
  Check(wcblSingle, WideCharByteLength(WideChar(WideString('{')[1])));
  Check(wcblSingle, WideCharByteLength(WideChar(WideString('|')[1])));
  Check(wcblSingle, WideCharByteLength(WideChar(WideString('}')[1])));
  Check(wcblSingle, WideCharByteLength(WideChar(WideString('。')[1])));
  Check(wcblSingle, WideCharByteLength(WideChar(WideString('「')[1])));
  Check(wcblSingle, WideCharByteLength(WideChar(WideString('」')[1])));
  Check(wcblSingle, WideCharByteLength(WideChar(WideString('、')[1])));
  Check(wcblSingle, WideCharByteLength(WideChar(WideString('・')[1])));
  Check(wcblSingle, WideCharByteLength(WideChar(WideString('ヲ')[1])));
  Check(wcblSingle, WideCharByteLength(WideChar(WideString('ァ')[1])));
  Check(wcblSingle, WideCharByteLength(WideChar(WideString('ィ')[1])));
  Check(wcblSingle, WideCharByteLength(WideChar(WideString('ゥ')[1])));
  Check(wcblSingle, WideCharByteLength(WideChar(WideString('ェ')[1])));
  Check(wcblSingle, WideCharByteLength(WideChar(WideString('ォ')[1])));
  Check(wcblSingle, WideCharByteLength(WideChar(WideString('ャ')[1])));
  Check(wcblSingle, WideCharByteLength(WideChar(WideString('ュ')[1])));
  Check(wcblSingle, WideCharByteLength(WideChar(WideString('ョ')[1])));
  Check(wcblSingle, WideCharByteLength(WideChar(WideString('ッ')[1])));
  Check(wcblSingle, WideCharByteLength(WideChar(WideString('ー')[1])));
  Check(wcblSingle, WideCharByteLength(WideChar(WideString('ア')[1])));
  Check(wcblSingle, WideCharByteLength(WideChar(WideString('イ')[1])));
  Check(wcblSingle, WideCharByteLength(WideChar(WideString('ウ')[1])));
  Check(wcblSingle, WideCharByteLength(WideChar(WideString('エ')[1])));
  Check(wcblSingle, WideCharByteLength(WideChar(WideString('オ')[1])));
  Check(wcblSingle, WideCharByteLength(WideChar(WideString('カ')[1])));
  Check(wcblSingle, WideCharByteLength(WideChar(WideString('キ')[1])));
  Check(wcblSingle, WideCharByteLength(WideChar(WideString('ク')[1])));
  Check(wcblSingle, WideCharByteLength(WideChar(WideString('ケ')[1])));
  Check(wcblSingle, WideCharByteLength(WideChar(WideString('コ')[1])));
  Check(wcblSingle, WideCharByteLength(WideChar(WideString('サ')[1])));
  Check(wcblSingle, WideCharByteLength(WideChar(WideString('シ')[1])));
  Check(wcblSingle, WideCharByteLength(WideChar(WideString('ス')[1])));
  Check(wcblSingle, WideCharByteLength(WideChar(WideString('セ')[1])));
  Check(wcblSingle, WideCharByteLength(WideChar(WideString('ソ')[1])));
  Check(wcblSingle, WideCharByteLength(WideChar(WideString('タ')[1])));
  Check(wcblSingle, WideCharByteLength(WideChar(WideString('チ')[1])));
  Check(wcblSingle, WideCharByteLength(WideChar(WideString('ツ')[1])));
  Check(wcblSingle, WideCharByteLength(WideChar(WideString('テ')[1])));
  Check(wcblSingle, WideCharByteLength(WideChar(WideString('ト')[1])));
  Check(wcblSingle, WideCharByteLength(WideChar(WideString('ナ')[1])));
  Check(wcblSingle, WideCharByteLength(WideChar(WideString('ニ')[1])));
  Check(wcblSingle, WideCharByteLength(WideChar(WideString('ヌ')[1])));
  Check(wcblSingle, WideCharByteLength(WideChar(WideString('ネ')[1])));
  Check(wcblSingle, WideCharByteLength(WideChar(WideString('ノ')[1])));
  Check(wcblSingle, WideCharByteLength(WideChar(WideString('ハ')[1])));
  Check(wcblSingle, WideCharByteLength(WideChar(WideString('ヒ')[1])));
  Check(wcblSingle, WideCharByteLength(WideChar(WideString('フ')[1])));
  Check(wcblSingle, WideCharByteLength(WideChar(WideString('ヘ')[1])));
  Check(wcblSingle, WideCharByteLength(WideChar(WideString('ホ')[1])));
  Check(wcblSingle, WideCharByteLength(WideChar(WideString('マ')[1])));
  Check(wcblSingle, WideCharByteLength(WideChar(WideString('ミ')[1])));
  Check(wcblSingle, WideCharByteLength(WideChar(WideString('ム')[1])));
  Check(wcblSingle, WideCharByteLength(WideChar(WideString('メ')[1])));
  Check(wcblSingle, WideCharByteLength(WideChar(WideString('モ')[1])));
  Check(wcblSingle, WideCharByteLength(WideChar(WideString('ヤ')[1])));
  Check(wcblSingle, WideCharByteLength(WideChar(WideString('ユ')[1])));
  Check(wcblSingle, WideCharByteLength(WideChar(WideString('ヨ')[1])));
  Check(wcblSingle, WideCharByteLength(WideChar(WideString('ラ')[1])));
  Check(wcblSingle, WideCharByteLength(WideChar(WideString('リ')[1])));
  Check(wcblSingle, WideCharByteLength(WideChar(WideString('ル')[1])));
  Check(wcblSingle, WideCharByteLength(WideChar(WideString('レ')[1])));
  Check(wcblSingle, WideCharByteLength(WideChar(WideString('ロ')[1])));
  Check(wcblSingle, WideCharByteLength(WideChar(WideString('ワ')[1])));
  Check(wcblSingle, WideCharByteLength(WideChar(WideString('ン')[1])));
  Check(wcblSingle, WideCharByteLength(WideChar(WideString('゛')[1])));
  Check(wcblSingle, WideCharByteLength(WideChar(WideString('゜')[1])));
  Check(wcblMulti, WideCharByteLength(WideChar(WideString('a')[1])));
  Check(wcblMulti, WideCharByteLength(WideChar(WideString('A')[1])));
end;


Fusa  2006-05-13 22:02:51  No: 21510

あ、解決時はチェックでした....(^〜^;)


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加