左の図のような感じのカウンターを作ります。SSIは使いません。IMGタグのところに
CGIプログラム名を書いて呼び出しています。
前準備として0から9までの数字を表示したGIF画像を用意しておきます。GIF画像の 名前はそれぞれ0.gif, 1.gif,...9.gifのようにします。背景は透明にしても、好みの 色にしてもよいでしょう。なるべく表示を軽くするために減色しておきます。これらのファイルは imgというフォルダを作って、そこに入れておきます。
また、logというフォルダを作っておきcount.txtというファイルを作っておきます。このファイルにはカウンタの初期値を6桁で書き込んでおきます。(1から表示したいなら000001のように書き込んでおきます。)
呼び出し側のHTMLは次のような感じになります。
<HTML> <HEAD> <meta http-equiv="Content-Type" content="text/html; charset=Shift_JIS"> <TITLE>カウンタ表示</TITLE> </HEAD> <BODY BGCOLOR="yellow"> <CENTER> <H1>カウンタ表示</H1> <IMG SRC="img02.cgi?1"> <IMG SRC="img02.cgi?2"> <IMG SRC="img02.cgi?3"> <IMG SRC="img02.cgi?4"> <IMG SRC="img02.cgi?5"> <IMG SRC="img02.cgi?6"> </CENTER> </BODY> </HTML>これを見てわかるように、IMGタグのところでCGIプログラム(img02.cgi)を呼び出しています。 また、プログラム名の後に「?」マークを入れて、プログラムに渡すデータを記載しています。 この場合、カウンタの先頭から順番に1,2,...6としてあります。(6桁表示)
通常はHTMLファイルを置く場所とCGIプログラムを置く場所は全然違うところになるので CGIプログラム名の前にディレクトリがつくのが普通です。
今回の方式ですとSSIが使用不可の環境でも実現できます。
では、プログラムはどうなっているのでしょうか。
// img02.c #define FCOUNT "log/count.txt" #include <stdio.h> #include <stdlib.h> #include <io.h> #include <fcntl.h> int loadpic(int, int); int main() { char *lpno; int keta; FILE *fp; int cnt; lpno = getenv("QUERY_STRING"); keta = atoi(lpno); //カウンタの読み込み fp = fopen(FCOUNT, "r"); if (fp == NULL) return -1; fscanf(fp, "%d", &cnt); fclose(fp); //画像出力関数を呼び出す loadpic(keta, cnt); //1桁目を出力したらカウンタの数値を増やして書き込み if (keta == 6) { cnt++; fp = fopen(FCOUNT, "w"); if (fp == NULL) return -1; fprintf(fp, "%06d", cnt); fclose(fp); } return 0; }main関数です。
lpno = getenv("QUERY_STRING");
これで、HTMLからCGIプログラムを呼び出すとき「?」以降に記載した文字列を 取得できます。ここでは、int型の数値に変換して変数ketaに格納しています。
次にcount.txtファイルから書き込まれている文字列を数値として読み込みcntに格納します。
そして、loadpic関数を呼び出します。
ketaが6まで来たらcntを1増やしてcount.txtファイルに上書きします。
int loadpic(int keta, int cnt) { int j; unsigned char buf[4]; FILE *fp; char szFname[16], szTemp[16]; //カウントを6桁の文字列に sprintf(szTemp, "%06d", cnt); //呼び出す画像ファイル名を作る sprintf(szFname, "img/%c.gif", szTemp[keta-1]); //画面に出力 printf("Content-type:image/gif\n\n"); fp = fopen(szFname, "rb"); if (fp == NULL) return -1; _setmode(_fileno(stdout), _O_BINARY); while (1) { j = (int)fread(buf, 1, 1, fp); fwrite(buf, 1, j, stdout); if (feof(fp)) break; } fclose(fp); return 0; }これは、ほとんど前章のプログラムと同じですね。
違うところは、引数のketaとcntから読み込んで表示するgif画像のファイル名を作っている点です。
今回も簡単でした。実際には、インターネットでは多くの人がアクセスするので、ファイル入出力 のところで、排他制御しないとファイルが破損するおそれがあります。
Update May/19/2003 By Y.Kumei