重要なお知らせ

「教えて! goo」は2025年9月17日(水)をもちまして、サービスを終了いたします。詳細はこちら>

【GOLF me!】初月無料お試し

フォームのaction で呼び出したdic.cgi が計算をして、二つの値$i,$maxを出し、それを、2つ用意した一行テキスト領域それぞれに入れたいのですが、どうやったらよいのでしょうか?

<form action="dic.cgi">
<input type=text name="count" value="$i">
<input type=text name="total" value="$max">
form>
ではエラーになりました。
どなたか、どうか教えて下さい。

A 回答 (13件中1~10件)

cgi-lib.plで &ReadParse(*f); を行っているのなら私が書いた QUERY_STRING を解析するロジックはいりません。

ReadParseがその処理ですから。$tango = $f{'tango'}と同様に取得できます。また、POST/GET、どちらのmethodでも $f{'hoge'}に格納してくれるので formの methodを POSTにすれば URLに不要な文字列が入りません。
また、ReadParseを使うことで %xxと書かれた部分の解析(変換)も行ってくれます。

では、私が書いたものの間違いを訂正しつつ動くように改造します。
form表示部分を
<INPUT type="submit" name="search" value="単語検索">
<INPUT type="submit" name="search" value="↑">
<INPUT type="submit" name="search" value="↓">
と直して下さい。

前後しますが判定部分を
if ($f{'search'} eq '単語検索') {
#単語検索
} elsif ($f{'search'} eq '↑') {
#デクリメント処理
} elsif ($f{'search'} eq '↓') {
#インクリメント処理
}

> print <<EOD;
> Content-type: text/html; charset=sjis-jp\n\n";
>
これは??
Content-type: text/html; charset=sjis-jp

(↑ここを必ず1行空けること)
です。
#私もてさぐりの所があるので冗長的な回答になってすいません。
    • good
    • 0
この回答へのお礼

yatokesaさま、おかげさまでできました。ゴールインです!感激です。手取り足取りご指導を受けました。感謝しております。これでひとまずこのページの基本部分ができました。

あとはFrame1に希望のニュースサイトを表示、それを記憶、一覧、選択し、入力部分はもっと改善して、検索表示される見出し語を表示するname=tango とはまた別に一行入力領域type=text name=inclimentbox を設置して、インクリメント表示方式で、一字入力毎に収録単語を先読みして下のtangoとtextarea=result に検索結果を示す、としたいと思います。
 そんな構想なんですが、次に最初に解決したい問題は、textarea内の表示に<BR>が出てしまっている点です。print $data という表示の仕方を念頭に入れたテキストデータ$data の<BR>をどのようにすれば、うまく改行表示として使えるでしょうか?
 yatokesa さま、この質問はあらたなスレッドでさせていただきますので、どうか、また引き続きご指導をいただきたく存じます。

お礼日時:2003/10/20 20:16

すいません、1日空いてしまいましたが、現状がどのようになっているか把握できませんので、現状の問題点について補足いただけますか?(お礼と補足がどちらの最後の書き込みか分からなかったので...)



dic.cgiの後ろに ? で続く文字列は formに書かれた内容をブラウザが送る文字列です。これはformのmethodに GETを指定してるからです。元々tonkaさんが書かれていたソースには何も指定していなかったので GETで送ればよいのかと思いました(省略時はGET)。

methodに POSTを指定すれば URLには書かれずに送信されます。この場合 CGI(Perl)には標準入力で formの値が渡されますので perlでその値を読み出す方法が変わります。GET/POSTで受け取る方法は様々なところで解説されているので割愛します。

> ところで表示の文字化けはどうすれば解消できるのでしょうか?

CGIが SHIFT_JISで 単語検索結果がそれ以外の文字コードなのでしょうか?それでしたら検索結果の文字コードに合わせて CGIの文字コードを保存し直し、ヘッダーのcharsetもそのコードに合わせるのが最も楽でしょう。
    • good
    • 0
この回答へのお礼

こちらこそ、ありがとうございました。なんと心強い応援をしていただいていることか!
検索が行われない状態が解決できません。ソースの一部をご覧下さい。
require 'cgi-lib.pl';

&ReadParse(*f);
$tango = $f{'tango'};

#print "Content-type: text/html; charset=sjis-jp\n\n";


@str = split ("&", $ENV{'QUERY_STRING'});
foreach $param (@str) {
($e, $v) = split ("=", $param);
$f{$e} = $v;
}

$i = $f{'nummer'};
$max = $f{'total'};
$tango = $f{'tango'};
chomp $tango;

# 辞書を読む
#ファイルの各行を配列に一括して読み込む。
open(IN, "GermJ.txt");
@list = <IN>;
close(IN);
$max = $#list;

if ($f{'submit'} eq '単語検索') {
#単語検索

for ($i=0; $i<$max; $i++)
{$data = @list[$i];
$pp=index($data, $tango.' /// ');
if ($pp==0)
{$pp=index($data,' /// ');
$data=substr($data, $pp+4);
$data=~ s/\\n/<BR>/g;
last;
}
}

} elsif ($f{'submit'} eq '↑') {
#デクリメント処理
$i--;
$data = @list[$i];
$pp=index($data,' /// ');
$data=substr($data, $pp+4);
$data=~ s/\\n/<BR>/g;

} elsif ($f{'submit'} eq '↓') {
#インクリメント処理
$i++;
$data = @list[$i];
$pp=index($data,' /// ');
$data=substr($data, $pp+4);
$data=~ s/\\n/<BR>/g;
}

print <<EOD;
Content-type: text/html; charset=sjis-jp\n\n";

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<HTML>
<HEAD>
<META http-equiv="Content-Type" content="text/html; charset=Shift_JIS">
<META http-equiv="Content-Style-Type" content="text/css">

<TITLE></TITLE>
</HEAD>
<BODY bgcolor="#b08317">
#<P> </P>
<FORM method="GET" action="dic.cgi" name="tangoform">
[略]
<form name="result">
<textarea>$data</textarea>
</form>
</BODY>
</HTML>
EOD
原因はどこにあるのでしょう。。。もしお教えいただければ幸いです。

お礼日時:2003/10/20 11:36

> *これでいいのでしょうか?まるで自信ありません。


%で指示するときはあまり意味がありませんが、残りの幅は勝手に計算してね、ぐらいの意味です。

> Perlスクリプトのどこで設定したらよいのでしょうか?
何も設定しなくて大丈夫ですよ。初回のdic.cgiの実行では当然 QUERY_STRINGに何も設定されていない状態ですから、$FORM{'nummer'}やその他には値がセットされていない状態ですが、Perlは変数を初期化しなければ空の値を返すでしょうから、プログラム上ではそれを期待したプログラムを作ればよいのです。
初回の表示ではブランクが表示されればいいのですから、変数を何もいじらなければ期待したブランクが表示されるはずです。

この回答への補足

yatokesa様、ご親切なアドバイスを引き続きいただきありがとうございます。
前回のご返事に書きましたあのtangokensaku.htm をApache2でテストしています。が、ブラウザーで呼び出してもフレームが出てきませんし、dic.cgiを実行していません。エラーはでませんでした。
 もっとも、ブラウザでいきなりdic.cgiを実行させるとおかげさまで、初期画面表示に成功します。フレームなしですが。(ただ、単語を入れて検索させようとすると、ブラウザのアドレス(D)にエラーのような文字が出ました
 原因が、初心者の私にはどうも分かりません。お教えいただけると幸いです。

補足日時:2003/10/19 11:29
    • good
    • 0
この回答へのお礼

yatokesa様、フレームが出てきませn. 、書きましたが、私のミスでした。出ました。検索結果が出ないのは、私の検索部分の書き方に問題があるに違いありません。調べてみます。どうも失礼しました。ところで表示の文字化けはどうすれば解消できるのでしょうか?
<META http-equiv="Content-Type" content="text/html; charset=Shift_JIS">
を書き直す必要がありますか?

お礼日時:2003/10/19 14:04

dic.cgi


---
@str = split ("&", $ENV{'QUERY_STRING'});
foreach $param (@str) {
($e, $v) = split ("=", $param);
$FORM{$e} = $v;
}

$i = $FORM{'nummer'};
$max = $FORM{'total'};

if ($FORM{'submit'} eq '単語検索') {
#単語検索
} elsif ($FORM{'submit'} eq '↑') {
#デクリメント処理
} elsif ($FORM{'submit'} eq '↓') {
#インクリメント処理
}

print <<EOD;
Content-type: text/html

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<HTML>
<HEAD>
<META http-equiv="Content-Type" content="text/html; charset=Shift_JIS">
<META http-equiv="Content-Style-Type" content="text/css">
<TITLE></TITLE>
</HEAD>
<BODY bgcolor="#b08317">
<P> </P>
<FORM method="GET" action="http://www.***.com/***.cgi" name="tangoform">
<INPUT size="20" type="text" name="tango">
<INPUT type="submit" name="tangosubmit" value="単語検索">
<INPUT type="submit" name="prev" value="↑">
<INPUT type="submit" name="next" value="↓">
<INPUT size="8" type="text" name="nummer" value="$i">
/ <INPUT size="9" type="text" name="total" value="$max">
</FORM>
<div align=right>
<INPUT type="submit" value="URLを登録">
<SELECT size="1" name="URLlistbox">
<OPTION value="bbbb" selected>aaaa</OPTION>
</SELECT>
</div>

<form name="result">
<textarea>$result_of_meaning</textarea>
</form>
</BODY>
</HTML>
EOD
---
適当ですがこんな感じでしょう。

<FRAMESET rows="50%,*">
<FRAME name="frame1" src="hoge.html">
<FRAME name="frame2" src="dic.cgi">
</FRAMESET>
このようにフレームを変更すればよいです。

この回答への補足

yatokesa 様、見捨てずにお教えいただき、どうもありがとうございます。
次のようなhtm ファイルを作って、Apache2でテストを始めました。dic.cgiのパスがApache2ディレクトリにしてあります。
tangokensaku.htm の中身を以下のように書きました。
<head><title>情報拾い読み・単語検索サイト<title></head>
<FRAMESET rows="50%,*">
<FRAME name="frame1" src="hoge.html">
<FRAME name="frame2" src="c:\Apache2\htdocs\dic\dic.cgi">
</FRAMESET>
</html>
*これでいいのでしょうか?まるで自信ありません。
dic.cgi のほうも御教示いただいたスクリプトに切り替えました。が、プログラム冒頭のフォーム部品"nummer"や"単語検索ボタン","↓","↑"などが画面上にまだ書かれていない状態でブラウザはdic.cgiを読みに行きますね。肝心の"tango"のボックスもまだありませんから、検索も行わず、$result_of_meaningは獲得できていないままの状態でおわってしまっていると思います。
 フォーム部品をどう、Perlスクリプトのどこで設定したらよいのでしょうか?
このプログラムの構成をお教えいただき、目から鱗が落ちるおもいです。こういう分岐をさせれば、私の前回の疑問は解消ですね。
 すみません、引き続き御教示をぜひお願い申し上げます。

補足日時:2003/10/18 22:41
    • good
    • 0

>私ができているのはForm から値を取得、


>CGIで処理(検索と結果表示)。できないでいるのは、
>画面上にあらかじめ設けてある二個の一行入力領域に、
>処理結果のpointer とデータ総量を書き込むことです。

そうですね、CGI/Perlでは無理です。サーバーサイド側のプログラムではクライアント側(ブラウザ)に文字列を送るだけの能力(HTTP通信)しかありませんから、クライアント側に既に送ってしまったhtmlを操作することはできません。

DHTMLやflashなども単ページ内での動作しかサポートしないでしょうから、(フレームに限らず)ページをまたがって内容を書き換えるには JavaScriptしかないでしょうね。#私はJavaScriptはよく知りません。
ただ、私個人の意見(というかポリシー)として、万人向けのwebページの場合、JavaScriptの動作を期待した機能の作り込みはあまり賛成したくないものです。イントラネット内での使用など、クライアント側の能力(機能)がわかっているのであればこの限りではありません。

プログラムの単純さと労力とを考えると、dic.cgiに入力フォームを表示させ、結果を textareaに表示させる方が楽な気がしたので#8ではアドバイスとして提案しました。

#6補足
>target="form2";
>document.tangoform.nummer.value= $i;
>document.tangoform.total.value= $max;
このスクリプトはどこに表示させるのでしょう? dic.cgi内(frame3)で表示しなければ動きませんよ。このとき、frame2を参照するのなら、window.parent.frame2.document.tangoform.number.value = $i; のようになると思います。#たぶん^^;)

この回答への補足

だんだん分かってきました。Perl の本を見ても入力値をGetすることばかり書かれていて、逆にその値を、たとえば1つインクリメントして、textarea に入れることは書かれていないので、それはできないのですね。当初の構想をあきらめます。
 #8のアドバイスに従って試みてみようと思います。
すでに御教示に従って次のようにしてあります。
print "<FORM action=\"dic.cgi\" name=\"tangoform\" target=\"frame2\">\n";
print "<input type=text name=\"number\" value=\"$i\">\n";
print "<input type=text name=\"total\" value=\"$max\">\n";
print "</form>\n";
この結果,ふたつのtextarea "number","total"が画面に生まれて値がそれぞれ入りました。
で次に、このnumber値を、ボタンを押したらインクリメントしたいのですが、どうすればnumber値を得られるのですか?
 とりあえず、この一つだけをご質問いたします。
(第2ぺーじへ回るべき古い質問として扱われ始めたので、そろそろ、これらの質問を新規に出すべきでしょうか?->GOO 管理者の方へ)

補足日時:2003/10/17 20:03
    • good
    • 0

すいません、ようやく意味が飲み込めました。


フレーム間でデータの受け渡しをしたいと言うことだったんですね。

フレームを3つに分ける理由は何でしょう?

2つのフレームにして、単語検索のフォームを含むCGIを下のフレームに表示、単語の検索結果は<textarea>に表示するようにするとかのほうが色々悩まなくてすむと思いました。

この回答への補足

一番最後に書きました内容は、確かに、フレーム間でデータの受け渡しができないので、教えていただきたい、ということです。
 でも、もともとはそれよりも、フォームから受け取った値を基にCGIプログラムを動かした後、得た値をこんどは別の(フレームは同じ)一行入力領域に書き込みたい、ということだったのです。値$iをname=countに、値$maxをname=total に入れたいのです。
 私の質問が大変稚拙なので伝わらないような気がしています。
 もう一度書きます。
 私ができているのはForm から値を取得、CGIで処理(検索と結果表示)。できないでいるのは、画面上にあらかじめ設けてある二個の一行入力領域に、処理結果のpointer とデータ総量を書き込むことです。

補足日時:2003/10/15 19:51
    • good
    • 0

このとき結果が別フレームへ表示されましたよね?



なので1~3は target="frame2" で。
4になったら target="frame3" と「targetも変更する」とよいかと。

ただ、フレームをいろいろコントロールしたい場合はJavaScriptを併用させる必要がでてくる可能性もありますので、そのときはJavaScriptの方へ質問したほうがよいかも。

この回答への補足

次のようにフレームを指定しても利きませんでした。
そこで疑いが。frame3に表示できているのは、単に、HomepageBuilder のtarget 属性設定でframe3に設定しているお陰であって、このperl スクリプトではframe操作が実現していないのではと。

print "<form action=\"dic.cgi\" name=\"tangoform\" method=\"POST\" target=\"frame3\">\n";
print "<input type=text name=\"nummer\" value=\"$i\">\n";
print "<input type=text name=\"total\" value=\"$max\">\n";
print "</form>\n";

#frame2 へも表示できるか?
print "<FORM action=\"dic.cgi\" name=\"tangoform\" target=\"frame2\">\n";
print "<input type=text name=\"nummer\" value=\"$i\">\n";
print "<input type=text name=\"total\" value=\"$max\">\n";
print "</form>\n";

それとも、すでに書きましたが、print <<"OEL";...でJavaSkript行を書く方向で検討すべきでしょうか?

補足日時:2003/10/15 01:46
    • good
    • 0

こういうCGIを検討してみてください。


1)GETやPOSTでデータが送られてきたかどうかをチェック
2)データがなかった場合は空の入力フォームを表示
3)データがあった場合はvalueにデータを入れて入力フォームを表示
4)すべての入力データが揃ったら結果を表示(結果は別フレームに表示させてもOK)

つまりCGIで入力フォームを丸々表示させるということです。
(No.2で訊いたのはそういうこと)

入力フォームはdicpage.htm。処理はdic.cgi。
このような構成で希望していることを実現させようとすると、「dic.cgiでdicpage.htmファイルを書き換える」という処理になってしまいます。これはかなり面倒です。フレームがからむと特に。

・・・このあたり、CGI vs JavaScriptでの得手/不得手という感じかな?

この回答への補足

feininger 様、おっしゃるとおり、No.2でのご指摘にもかかわらず、わたしは、何とかして、dicpage.htm (フレームで3つに区切られています) と dic.cgi を共存させようとしています。上記の1)~4)はできていると言えると思うのですけど。。ただ4)の(結果は別フレームに表示させてもOK)を実現できていません。次のようにしてもだめでした。変数$i,$max の値を別フレームに出せません。

print <<"EOL";
<SCRIPT language="JavaScript"><!--
target="form2";
document.tangoform.nummer.value= $i;
document.tangoform.total.value= $max;
//-->
</SCRIPT>
EOL
初心者なので申し訳ありません。どうかよろしくご指導下さい。フレーム設計を放棄したくありません。理由は、最上のframe1にURLで独・伊語のニュースを表示したいのです。

補足日時:2003/10/14 23:14
    • good
    • 0

ごめんなさい、私が勘違いしていましたね。

#1さんは適切な回答をされていると思いますよ。
$i, $maxに期待した値が格納されているのなら print文で問題なく出力されます。

固定の数値を form/input text で出力する理由は分かりませんが、valueに値をセットする方法は間違いではありません。#1さんの仰るように ' (シングルクォート) " (ダブルクォート)の使い方、\エスケープ等を見直されることをお薦めします。

また参考までに
print <<EOD;
<form action="dic.cgi">
<input type=text name="count" value="$i">
<input type=text name="total" value="$max">
</form>
EOD
という書き方もできますし、
printf ("<input type=text name=\"count\" value=\"%d\">", $i);
と言う書き方もできます。
    • good
    • 0
この回答へのお礼

printで出力すると、どうしてもフォームの値入力ボックスができてしまい、そこにこの二つの変数$i, $max が入ってしまいます。
 そうではなくて、何とかして上部右端の二つのボックス(左端ではなく)にこの値を入れて、次の見出し語をアクセスするときのポインタとしたいのです。やはりprint によるのでしょうか?
ほんとに、皆様お助けいただいて感謝しております。どうか、さらに引き続きご指導をお願いいたします。

お礼日時:2003/10/14 17:28

><input type=text name="count" value="$i">


><input type=text name="total" value="$max">
このようにHTMLに書いても$i, $maxはperlの変数にはなりません。valueはhtmlでテキストボックスを表示するときの初期値になります。
perlでform上のテキストボックスに入力された値を読み出すには、formのmethodがGETの場合、環境変数 QUERY_STRING、POSTの場合は標準入力で渡された値を適切に加工して受け取る必要があります。
    • good
    • 0
この回答へのお礼

皆様、ご親切に御教示いただきありがとうございます。
できればいいと願っておりますのは、ある二つの一行入力ボックス(nameは"count"と"total")に、単語のポインタと全単語数をperlプログラムで入れることなんです。printメソッドではだめだということは分かりました。
 よろしくお願いします。

お礼日時:2003/10/13 21:38

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!