たとえば次のようなフォームを作ってみましょう。
<title>フォームのテスト</title> <h1>フォームのテスト</h1> <form action="test.cgi" method="post"> <p>メッセージ: <input name="message" size=60> </form>
このフォームに書き込むと test.cgi というCGIが起動します。これはたとえば次のように作っておきます。
#include <iostream>
#include <string>
using namespace std;
int main()
{
string s;
cin >> s;
cout << "Content-type: text/html\n\n";
cout << s << endl;
}
これでたとえば「Hello」と打ち込むと,
message=Helloと返ります。
メッセージの頭に「message= という余分な部分が付きましたね。 これは
<input name="message" ...>と指定したからです。 この部分を削るには substr() という関数を使います。 たとえば上の s を s.substr(8) にすると,最初から8文字を削ってくれます。
上のフォームは日本語を入力すると変になりますね。 次のように関数を使って変換します。
#include <iostream>
#include <string>
using namespace std;
string decode(const string& s)
{
string t;
string::const_iterator p = s.begin();
while (p != s.end()) {
if (*p == '%') {
if (++p == s.end()) break;
int d = *p;
if (++p == s.end()) break;
int e = *p;
d = (d >= 'A') ? (d & 0xdf) - 'A' + 10 : d - '0';
e = (e >= 'A') ? (e & 0xdf) - 'A' + 10 : e - '0';
if (d >= 0 && d < 16 && e >= 0 && e < 16)
t += char(16 * d + e);
} else if (*p == '+') {
t += ' ';
} else if (*p == '&') {
t += '\n';
} else {
t += *p;
}
p++;
}
return t;
}
int main()
{
string s;
cin >> s;
s = decode(s);
cout << "Content-type: text/html\n\n";
cout << s.substr(8) << endl;
}
書き込んだ内容をファイルに追加(アペンド) していけばチャットや掲示板になります。
たとえば上の「フォームのテスト」のファイル名が formtest.html だったとすると,次のような CGI にすれば,formtest.html に書き込んだ内容がどんどんアペンドされていきます。
int main()
{
string s;
cin >> s;
cout << "Content-type: text/html\n\n";
ofstream out("formtest.html", ios_base::app);
out << "<p>" << decode(s).substr(8) << endl;
cout << "<p>書き込みました\n";
}
「書き込みました」の下に「戻る」リンクを付けてみましょう。 あるいは自動的に戻るようにするにはどうしたらいいでしょうか (ヒントは ここ)。
★もっと本格的なチャットプログラムの C++ ソースと解説は ここ にあります。 掲示板の C++ ソースと解説は ここ にあります。
アンケートやクイズを作ってみましょう。
<form action="test.cgi" method="post"> <p>性別: <input type="radio" name="1" value="M">男 <input type="radio" name="1" value="F">女 <p>趣味: <input type="radio" name="2" value="1">遊び <input type="radio" name="2" value="2">勉強 <input type="radio" name="2" value="3">なし <input type="submit" value="送る"> <input type="reset" value="クリア"> </form>
test.cgi はこのページの最初のもの(decode() を使っていないもの)をとりあえず使ってみましょう。 たとえば「女」「遊び」を選ぶと,
1=F&2=1と表示されます。つまり,name= で指定した名前と,value= で指定した値が = で結ばれて送られます。項目の区切りは & になります。
これから特定の場所を切り出すには,s[番号] という使い方をします。 番号 は文字の位置で,0 から始まる番号で数えます。
たとえば次のようにできます。
#include <iostream>
#include <string>
using namespace std;
int main()
{
string s;
cin >> s;
cout << "Content-type: text/html\n\n";
if (s[2] == 'M')
cout << "<p>あなたは男ですね\n";
else
cout << "<p>あなたは女ですね\n";
if (s[6] == '1')
cout << "<p>遊びはほどほどにね!\n";
}
リンクはご自由にどうぞ。
松阪大学 奥村晴彦 okumura@matsusaka-u.ac.jp
Last modified: Thu Dec 16 22:47:37 1999