[← TpAddYen|With TeraPad|Menu|Top ]
last updated: 2009.10.19
例えば CGI のスクリプティング言語として有名な perl では、「print」 という、指定した文字をそのまま表示する命令があります。 例えば、
print "こんにちは。はじめまして。";
と書くと、
こんにちは。はじめまして。
と表示されます。 ここで、
print "こんにちは。\nはじめまして。";
というように 「\n」 をはさんで書くと、
こんにちは。
はじめまして。
と表示されます。改行されていますね。 「n」 はただの n なのに、その直前に 「\」 をつけることによって、改行するという動作に変わっています。 そして、「n」 そのものは出力されていません。
この 「\n」 のように、ある特定の文字の前に 「\」 をつけることによって特別な操作が行われるようにすることを、エスケープシーケンスといいます。
※ Perl、csh、C/C++ のエスケープシーケンス機能は厳密に言うと、それぞれ微妙に違います。が、似たようなものです (笑)
ところで、「\」 文字や 「"」 文字を表示したいという場合にはどうすればいいのでしょうか。
「\」 をただそのまま書いても、エスケープシーケンスの開始とみなされてしまいます。 また、「"」 を書こうものなら、その場で文字列が途切れてしまい、文法エラーになってしまいます。
print "これ \ は、円マークです。";
※ 「\」 は無視される
print "これ " は、ダブルクォーテーションです。";
※ "これ " で文字列が閉じてしまうのに、その次にいきなり 「は、〜」 と始まるので文法エラー
実は 「\」 エスケープは、その次に指定された文字がエスケープシーケンスとして無効である場合には、「\」 を取り除いた上でその文字をそのまま表示します。 なのでこの場合は、
print "これ \\ は、円マークです。";
print "これ \" は、ダブルクォーテーションです。";
※ 「\"」 では文字列を閉じたことにはならない
と書きます。そうするとちゃんと
これ \ は、円マークです。
これ " は、ダブルクォーテーションです。
と表示されます。
「\」 という文字をエスケープシーケンスの開始とみなす 「日本語未対応」 の処理系の場合、Shift_JIS の 2 バイト文字 (いわゆる全角文字) を扱わせると問題が出てくることがあります。 例えば
print "これからの予定";
と書くと、
これからの嵐
と表示されます。
なんか文字が変わってしまっていますね。。
また、
print "貼り付け機能";
とか書くと、今度はいきなり文法エラーになってしまい、プログラムの実行すらできなくなります・・・うー。
このような問題が発生する理由は、Shift_JIS には、2 バイト目に 「\」 と同じ文字コードを含む文字がいくつかあるためです。 日本語未対応の処理系では、ひらがなや漢字などの 2 バイト文字は 2 文字として扱ってしまうため、日本語で表示した時に 「\」 が見えなくても、「\」 が指定されたと勘違いします (笑)
※ 日本語対応の処理系では、2 バイト文字でも 1 文字として扱うので、特に問題はありません。
ちなみに、どの文字に含まれているかは、英字フォントで表示させてみればわかります。
日本語フォント | こ れ か ら の 予 定 | 貼 り 付 け 機 能 |
---|---|---|
英字フォント | ,+ ,e ,c ,c ,I -\ 'e | "\ ,e .t ,~ <@ "\ |
※ 表示できない文字は、それに近い ASCII 文字で書いてみました。
※ 英字フォントでは、「\」 は 「\」 (バックスラッシュ) で表示されます。
という事で、先ほどの print 命令は、(「日本語未対応の処理系」 から見ると) それぞれ
print ",+,e,c,c,I-\'e"; # これからの予定
print ""\,e.t,~<@"\"; # 貼り付け機能
と書いたことになります。 で、上記の通り、「\」 エスケープは、その次に指定された文字がエスケープシーケンスとして無効である場合には、「\」 を取り除いた上でその文字をそのまま表示するために、「\」 が取り除かれる形になってしまうのです。
ちなみになぜ 「予定」 → 「嵐」 なのかと言うと、それは文字コードを調べてみればわかります。
予 → [975C]
定 → [92E8]
なので、「予定」 を 1 バイトずつ表すと、
[97] [5C] [92] [E8]
になります。ここで、「\」 (文字コード 5C) を取り除くと、
[97] [92] [E8]
となります。で、
[9792] → 嵐
となるわけです。
※ しかし、「予定」 → 「嵐」 って・・・よりによって 「嵐」 って・・・何かの暗示でしょーか??
※ っていうか、[E8] が余ってるなあ・・・。不気味だなあ・・・。。
また、「貼り付け機能」 の方は、文字列を閉じるつもりで書いた 「"」 が文字列の一部として扱われてしまい、
print ""\,e.t,~<@"\"; # 貼り付け機能
※ 「\"」 では文字列を閉じたことにはならない
そのため文字列を全然閉じていないことになるので文法エラーとなります。
この問題を回避するには、いくつかの方法があります。
これが一般的な回避方法です。
EUC-JP には、「エスケープコードを含む 2 バイト文字」 が存在しないので、この問題は発生しません。
※ 中には、こういう理由があると知らずに EUC-JP にしてる人も・・・。
※ ちょうど TeraPad も EUC-JP での保存に対応している事だし・・・。
ただし、この方法では、Shift_JIS での出力が要求されるプログラムには対応できません。
※ 例えば、i-mode 対応の CGI とか。。
この問題が発生するのは、処理系がプログラムを解釈する時だけです。 なので、外部にメッセージを定義したファイルを用意して、そこから読み込むという具合にすれば、化けたりしません。
もちろん、そういう風にプログラムを作るのは面倒です。 ええ、そりゃあもう。
そういう問題のある文字を使っていなければ、当然問題は起こりません。
が・・・かなりの頻度で使われる文字もいくつか含んでいたり・・・。
一般に 「ダメ文字」 と呼ばれる文字です。
― [815C] | ソ [835C] | Ы [845C] | IX [875C] | 噂 [895C] | 浬 [8A5C] | 欺 [8B5C] |
圭 [8C5C] | 構 [8D5C] | 蚕 [8E5C] | 十 [8F5C] | 申 [905C] | 曾 [915C] | 箪 [925C] |
貼 [935C] | 能 [945C] | 表 [955C] | 暴 [965C] | 予 [975C] | 禄 [985C] | 兔 [995C] |
喀 [9A5C] | 媾 [9B5C] | 彌 [9C5C] | 拿 [9D5C] | 杤 [9E5C] | 歃 [9F5C] | 濬 [E05C] |
畚 [E15C] | 秉 [E25C] | 綵 [E35C] | 臀 [E45C] | 藹 [E55C] | 觸 [E65C] | 軆 [E75C] |
鐔 [E85C] | 饅 [E95C] | 鷭 [EA5C] | x [ED5C] | x [EE5C] | \ [FA5C] | \ [FB5C] |
※ 抜けがあるかもしれません・・・。
要は、「\」 が勝手に消えてしまうのが問題なわけであって、「\」 が消えないようにその後ろにもう一つ 「\」 を置いてやると、この問題は回避できます。
print "これからの予\定";
print "貼\り付け機能\";
これを自動で行うのが、今回リリースの 「TpAddYen」 です♪
[← TpAddYen|With TeraPad|Menu|Top ]
©2000-2008 Tategoto, all right reserved.