Delphi Programming / Object Pascal
サイトのトップページへ リンクのページへ ロゴマーク
[掲載 2014年12月30日] [更新 2014年12月30日] Delphi 一般・その他
   
円記号問題 - 円記号 ( ¥ ) とバックスラッシュ ( \ )
動作確認等 Windows 7 U64(SP1) + Delphi XE(UP1) Pro
[整理番号 - 0900]







円記号 ( ¥ ) とバックスラッシュ ( \ )


円記号 (¥) と,バックスラッシュ (\) は,主に以下のように使用されています.
  • ¥ (円記号) は,日本,中国では通貨記号 (金額を表す数字の前に表記する)
  • ¥ (円記号) は,日本語フォントの環境では,パスの区切り文字
  • \ (バックスラッシュ) は,パスの区切り文字 (デリミタ)
  • \ (バックスラッシュ) は,コマンド類の識別文字として使用されることがある
¥ (円記号) の文字コードは U+00A5 ですが,文章の中で円記号を書いた場合,Microsoft Windows では,以下のように変換されます (ユニコードの場合).
  • ¥ (円記号) は,文字コード U+005C のバックスラッシュに変換される
  • ただし,日本語フォントの環境では,この U+005C の文字は円記号で表示される
したがって,文字列内に円記号を直接書いた場合,これらは,パスの区切り文字等のバックスラッシュとして解釈されることになります.そのため,円記号をバックスラッシュ以外の文字として扱いたい場合に問題となることがあります.
非ユニコード文字の場合,場合によっては,円記号の文字が制御コードの一部として解釈されてしまうことがあります.


[備考 1]
「円記号」を英訳する場合,例えば「ファイル名のパスの区切りには円記号を使用します」を英訳した時に,円記号が yen symbol では困ります.本ページの記事のように,yen symbol と訳さなければならない場合もあります.


[備考 2]
ワードやエクセルで ¥ (円記号) を入力してしても,\ (バックスラッシュ) になってしまう場合,その位置のフォントが英文フォントになっている可能性があります.文字列を選択して,日本語のフォントにすると円記号になります.ワードやエクセルでは,半角の文字と全角の文字のデフォルトのフォントを別々に設定できます.


[備考 3]
U+005C の U+ はユニコードを意味します.同じ文字でも,ユニコードと Ansi 文字では文字のコード (コードポイント) が違う場合があります.ユニコードの文字のコード (コードポイント) であることを明示する際に使用します.
実際の文字コード (コードポイント) の値は 005C です.





01_¥ をバックスラッシュではない文字として扱う例  -  通貨記号


円記号の問題を確認するいい例が以下のページにあります.
下のコードは,金額の数値を通貨としての文字列に変換し,右端揃えで表示します.その際,通貨記号の ¥ 記号を削除します.下図は,そのページのコードを実際に実行して確認した図です.

ユニコード版の Delphi XE では円記号は削除できていません.
一方,非ユニコード版の Delphi 2007 では削除できています.非ユニコード版で,常に円記号がこのように処理できるわけではありません.例えば,前項の参考リンクの LCMapString 関数では,半角の円記号を全角の円記号に変換できません.



図1
Windows 7 U64(SP1) + Delphi XE(UP1) Pro の場合
  • ユニコードでは,¥ (円記号) はパスの区切り文字として扱われるので,削除はできない
図2
Windows 7 U64(SP1) + Delphi 2007-R2 Pro の場合
  • Delphi 2007 はユニコード版ではないので, ¥ (円記号) をパス区切り文字以外として認識する
  • ただし,これは Delete 関数の場合

リスト1
円記号をパス区切り文字以外として扱う例
ユニコードではパス区切り文字として扱われてしまう
//=============================================================================
//  フォーム生成時の処理
//=============================================================================
procedure TForm1.FormCreate(Sender: TObject);
begin
  Memo1.Lines.Clear;
  Memo1.font.Name  := 'MS ゴシック';
  Memo1.Font.Size  := 10;
  Memo1.ScrollBars := ssVertical;
end;

//-----------------------------------------------------------------------------
//  数値を3桁ごとにカンマを付けた書式文字列に変換
//  \(円記号)は削除する
//-----------------------------------------------------------------------------
function GetFormattedPrice(Price: Currency): String;
begin
  Result := (Format('%14m円', [Price]));
  Delete(Result,Pos('\', Result),1);
end;

//=============================================================================
//  数値を右揃えで表示する例
//=============================================================================
procedure TForm1.Button1Click(Sender: TObject);
begin
  Memo1.Lines.Add(GetFormattedPrice(123456789));
  Memo1.Lines.Add(GetFormattedPrice(123));
  Memo1.Lines.Add(GetFormattedPrice(-12345));
  Memo1.Lines.Add(GetFormattedPrice(12345));
end;




02_¥ をバックスラッシュ以外として扱うには U+00A5 を使用


円記号を ¥ という文字として扱うには,文字コードの U+00A5 を直接指定します.次のコードは,前項のリンクの記事と同じように変更したものです.
実行結果を見ると,円記号 (¥) が削除できていることが分かります.

本サンプルは,通貨記号ということが分かっている例です.しかし,文字列の中の ¥ が,¥ そのものであるか,パスの区切り文字等のバックスラッシュとして扱うべきなのかの判断が難しい場面もあるかも知れません.円記号 (¥) を検出しようとしても,U+005C のバックスラッシュ文字として検出されてしまうことがあります.



図3
Windows 7 U64(SP1) + Delphi XE(UP1) Pro の場合
  • 期待通りの結果となっている
図4
Windows 7 U64(SP1) + Delphi 2007-R2 Pro の場合
  • Delphi 2007 では,#$00A5 は ¥ として認識しない

リスト2
円記号として,文字コードの U+00A5 を指定すれば,¥ 文字として扱える
ただし,文字のコードページがユニコードの場合
//-----------------------------------------------------------------------------
//  数値を3桁ごとにカンマを付けた書式文字列に変換
//  \(円記号)は削除する
//-----------------------------------------------------------------------------
function GetFormattedPrice(Price: Currency): String;
const
  Yen = #$00A5;
begin
  Result := (Format('%14m円', [Price]));
  Delete(Result,Pos(Yen, Result),1);
end;


非ユニコード版の Delphi 2007 以前では,文字は Ansi 文字として扱われます.円記号を ¥ という文字として扱うには,以下のように,文字コードを $5C とします.
Ansi 文字では,¥\ の文字コードは同じ $5C です.どちらの文字が表示されるかは,フォントの種類によります.Ansi 文字の $A5 は全く別の文字です.

Windows XP でユニコードが実装されましたが,意識的に設定しない限り文字コードはユニコードとして扱われませんでした.Windows Vista では全面的にユニコード化されました.




//-----------------------------------------------------------------------------
//  数値を3桁ごとにカンマを付けた書式文字列に変換
//  \(円記号)は削除する
//-----------------------------------------------------------------------------
function GetFormattedPrice(Price: Currency): String;
const
{$IFDEF Unicode} //Delphi 2009以降
  Yen = #$00A5;
{$ELSE}
  Yen = #$5C;
{$ENDIF}
begin
  Result := (Format('%14m円', [Price]));
  Delete(Result,Pos(Yen, Result),1);
end;