***HPクリエイターのためのCGI講座 第41回***
3.2 複数ケタのカウンター

前項のカウンターは1ケタしか表示できませんでした。
これでは、実用になりませんね。
では、どのようにすれば、複数ケタの表示を可能に出来るのでしょうか?
ちょっと、面倒ですが桁数分のCGIプログラムを呼び出すと言う手もありますね。
つまり、1ケタ目のCGI、2ケタ目のCGIと言った具合にCGIプログラムをケタ数分用意する訳です。
これでも可能ですが、どのケタのCGIプログラムから起動されるか保証されないため、複雑なプログラムになります。
HPを見ていて、画像の表示が順番(例えば上から下)でないことは経験上ご存知でしょう。
HTML文章に、<img src="0.gif"> のようなタグをケタ数だけ出力する、と言うやり方もあります。
これは、よく使われる手法で、実用的です。
ただし、ケタ数の数字画像gifファイルを別々に送るので、時間がかかります。

gif画像を合成して、複数ケタを表示する方法を紹介します。
gif画像の合成にはとほほさん(http://wakusei.cplaza.ne.jp/twn/)が提供しているサブルーチンを使用します。
サブルーチンとは、プログラムから呼び出せるプログラムのことであることは、以前に説明しましたね。

この方法で作成したカウンターを作成してあるので、「複数ケタのカウンター」をクリックしてください。
最上部に4ケタのカウンターを、黄色の枠に、このカウンターを表示しているCGIプログラムを表示しています。

まずは、HPのHTMLソースコードをご覧ください。
下記の記述が、ありますね。
<P><IMG src="n_cnt.cgi"></P>
この記述にから、このページが開かれる度に、n_cnt.cgiが起動されます。
タグの書き方は、前項の1ケタカウンターと同じですね。

では、n_cnt.cgi について、説明しましょう。

require 'gifcat.pl';
このプログラムはとほほさんの作成したサブルーチンを使用します。
このサブルーチンは、別ファイルに定義されているので、どこのファイルに定義されているかを指定します。
この場合、gifcat.pl と言うファイルにとほほさんのサブルーチンが格納されています。

open(IN,"<n_cnt.dat") || &error;
前項と同じように、カウンター値用ファイル(n_cnt.dat)を読み込みモードでオープンします。
前項との違いは、ファイル・アクセスへのエラー処理が追加された事です。
今までファイルへのエラー処理は、省略してきましたが、実用プログラムではエラー処理は必須です。
|| 演算子を覚えていますか?(Perl入門 3.論理演算子)
「左のオペランドが真のとき左のオペランドを、違った場合は右のオペランドを返します」でしたね。
open 関数は失敗すれば 偽 を返します。
つまり、open 関数に失敗すれば右のオペランド、&errorが評価されます。
error は、このプログラムの下のほうで定義されている、エラー処理を行うためのブルーチンです。
このように、サブルーチンを呼び出す場合は& をサブルーチン名の頭に付けます。
(組み込み関数には & は付かない)

$cnt = <IN>;
カウンタ値の読込み

close(IN);
ファイルのクローズ

$cnt++;
カウンタ値を1UP

if($cnt >= 10000) {$cnt = 0;}
カウンタ値が10000以上であれば0にする

open(OUT,">n_cnt.dat") || &error; n_cnt.datを書込みオープン

print OUT $cnt;
カウンタ値の書込み

close(OUT);
ファイルのクローズ

$k1000 = int($cnt / 1000);
$cnt -= $k1000 * 1000;
$k100 = int($cnt / 100);
$cnt -= $k100 * 100;
$k10 = int($cnt / 10);
$k1 = $cnt - $k10 * 10;
カウンター値を1000のケタ、100のケタ、10のケタ、1のケタに分解しています。
intは整数値を返す組み込み関数です。
=例=
$a = int(8/3); # $a には 2 が入る (8/3 は2.666・・・である、この整数部は 2)

上記プログラムの実行例 |
$cntに425が入っていた場合

$k1000 = int($cnt / 1000);
$cnt / 1000 は 0.425、この結果の整数部は 0
$k1000には 0 が設定される
$cnt -= $k1000 * 1000;
$k1000 * 1000 は 0、$cntから0を引いても結果は変わらないので $cnt は 425
$k100 = int($cnt / 100);
$cnt / 100 は 4.25、この結果の整数部は 4
$k100には 4 が設定される
$cnt -= $k100 * 100;
$k100 * 100 は 400、$cntから400を引いているので $cnt は 25
$k10 = int($cnt / 10);
$cnt / 10 は 2.5、この結果の整数部は 2
$k10には 2 が設定される
$k1 = $cnt - $k10 * 10;
ここの式は 25 - 2 * 10 と評価されるので、$k1 は 5 が設定される

つまり、$cntに425が入っていた場合、
$k1000 には 0
$k100 には 4
$k10 には 2
$k1 には 5
が設定される

ここで紹介した手法は、お世辞にも良い手法とは言えません。
ある目的に達するためのプログラミング手法は、無数に存在します。
このプログラミング手法のことを、アルゴリズムと言います。
プログラミングとは、このアルゴリズムを考えることです。
綺麗な、アルゴリズムを作るには、やはり経験が必要です。
数多くのプログラムを作ったり読んだりして、センスを磨いてください


print "Content-type: image/gif\n\n";
gifデータを送ることをブラウザへ通知

print &gifcat'gifcat("c1_$k1000.gif","c1_$k100.gif","c1_$k10.gif","c1_$k1.gif");
&gifcat'gifcatは、とほほさんが作られたサブルーチンで、複数のgifファイルを1つに合成します。
4つのgifファイル(数字図形ファイル)を一つに合成して、ブラウザに送っています。

sub error {
#エラー処理を書く 本来エラー処理を記述
exit;
}
サブルーチンの書き方は次の通りです。
sub XXXX{
    〜〜〜;
    〜〜〜;
}
XXXXにサブルーチン名を記述します。
サブルーチンは通常、呼び出し元に戻ります。
しかし、エラー処理後のような場合、プログラムの続きを実行させずに、そのままプログラムを終わらせたい場合があります。
exit は、このように、強制的にプログラムを終わらせる組み込み関数です。


********************************************************************************
講師:ALK alk@arkland.co.jp
運営:アークランド(株) http://www.arkland.co.jp/