• ベストアンサー

ランダムに1行読込み フォーム文字との同異を 判定するには?

txt ファイル から ランダムに 1行読み込んで それが フォームの入力文字と同じかを 判定し、 同じならば、次のファイルへ飛ぶ には、 どうしたらよいのでしょうか? お教えください。 ------------------------------------------------------ mondai.txt に 問題を 1行に 1題ずつ kotae.txt に 解答を 1行に ひとつずつ 書きました。 mondai.txt の 1行目の 解答が kotae.txt の 1行目 (2行目-10行目、同じ)としました。 001.cgi で 正解すれば 002.cgi を開く 不正解なら もう一度 001.cgi を実行。 問題は ランダムに 表示する。 まず、mondai.txt と kotae.txt を それぞれ 10行にして やってみました。 ------------------------------------------------------ すると、問題は ランダムに表示されました。 しかし、 ##################################################### if (param('answer') eq ("$ans")){ print "Location:$num2.cgi\n\n"; ・・・ { ##################################################### が、うまくいきません。 ↓こうしてあります。どうしたら、よいでしょうか? ↓解答したことを file.txt に記録しよう、ともしています。 ↓ ################ はじめ ############################## #!/usr/bin/perl -T use strict; use warnings; use CGI qw(-debug :standard); my ($sec,$min,$hour,$day,$mon,$year,$wday,$yday,$isdst) = localtime(time); $year += 1900; $mon = sprintf("%02d", $mon + 1); $day = sprintf("%02d", $day); $hour = sprintf("%02d", $hour); $min = sprintf("%02d", $min); $sec = sprintf("%02d", $sec); my $num = ('1267'); my $num2 = $num + 1; my $value = param('answer'); open(FILE, "../../mondai.txt"); my @data2 = <FILE>; close(FILE); open(FILE, "../../kotae.txt"); my @data3 = <FILE>; close(FILE); my $i = int(rand(10)); my $ans = $data3[$i]; if (param('answer') eq ("$ans")){ print "Location:$num2.cgi\n\n"; open(FILE, '<+file.txt') or die "$!"; my @DATA = <FILE>; close(FILE); open(FILE, '>file.txt') or die "$!"; print FILE ("$num,$ans,$year年$mon月$day日 $hour時$min分$sec秒\n"); print FILE (@DATA); close(FILE); } else { print header(-charset => 'Shift_JIS'); print start_html("$num.cgi"); print ('<font face="century">'); print $data2[$i]; #####---問題表示 print br; print startform( -method => 'POST', -action => "$num.cgi" ); print blockquote( textfield( -name => 'answer', -size => '70', -id => "next", -accesskey => '[' ) ); print <<END; <script type="text/javascript" language="JavaScript"> document.getElementById('next').focus(); </script> END print submit(-value => 'Send ( ↑Alt+[ )'); print endform; } ################ おわり ############################## よろしく、お願いいたします。

  • Perl
  • 回答数3
  • ありがとう数3

質問者が選んだベストアンサー

  • ベストアンサー
  • 15mm
  • ベストアンサー率65% (65/100)
回答No.3

もう回答がいくらか出ているので細かいことは言いませんが、以下のことも確認してみてください。 ファイルから読み取ったデータには、各行の最後に「\n」(改行)が入っていたりします。 (フォームの回答「aaa」とファイル内の解答「aaa\n」はeqにはなりません) if文のところをこんな風にいじってみてください if (param('answer') eq $ans){   ↓ if (param('answer')."\n" eq $ans){ もしくは if (param('answer') eq chop($ans)){ 改行コードが\nであること前提の話ですが以上です。

ttaa100kkaa
質問者

お礼

ご回答、まことにありがとうございました。

その他の回答 (2)

回答No.2

簡単にしかコードを読んでいないのですが、 どうも気になる点があったので回答します。 やりたい事は、別々のファイルに記述された問題と答えを、 ランダムで1問読み込んで解答の判定をしたいということですね。 まず、最初に実行した時に、 $i に乱数が入ります。そして、それを元に問題が出されます。 そして、答えを入力して送信していますね? しかし、答え合わせをする為に、送信した時に、 また、$i に乱数が作られているので、 問題番号と解答番号が一致しておりません。 これでは、正しい答えを入力しても、 10回に1回しか正解になりません。 答えを送信する時に、一緒に問題番号を送信して、 答えは、その問題番号から引き出してくると良いでしょう。

ttaa100kkaa
質問者

お礼

ご親切なご指摘、ありがとうございました。

  • sakusaker7
  • ベストアンサー率62% (800/1280)
回答No.1

if の判定が期待通りできてないということですか? >if (param('answer') eq ("$ans")){ $ans のほうの末尾に改行がくっついてませんか? それから、この場合の$ansをダブルクォートで括る必要はありません。 >print start_html("$num.cgi"); とか >-action => "$num.cgi" もそうですね。

ttaa100kkaa
質問者

お礼

ご回答、まことにありがとうございました。

ttaa100kkaa
質問者

補足

ご回答、まことに、ありがとうございます。 はい、 if の判定が期待通りできてないということです。 問題が question-01 のとき 解答を answer-01 と フォームに書いても 1276.cgi のままで、 1277.cgi へ飛びません。 ----↑my $num = ('1267'); の時です。----- ありがとうございました。

関連するQ&A

  • Perlでの Timeの足し算

    時間の足し算をやりたい。訳あってライブラリが使えません。 方法は無いでしょうか? 仮にライブラリが使えるなら、下記のようでうまく行っています。 --------------------------------------------------- use Time::Local; $year=2008; $mon =10; $mday=24; $hours = 23; $min = 0; $sec = 0; $time = timelocal($sec, $min, $hours, $mday, $mon - 1, $year); $a1=($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst) = localtime($time ); $mytimeORG= sprintf("%04d/%02d/%02d %2d:%2d", $year + 1900, $mon +1, $mday,$hour,$min); print "$mytimeORG\n"; ($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst) = localtime($time + 32400); #9H加算 $mytime9H= sprintf("%04d/%02d/%02d %02d:%02d", $year + 1900, $mon +1, $mday,$hour,$min); print "$mytime9H\n"; ---------------------------------------------

    • ベストアンサー
    • Perl
  • 掲示板への書き込み時間

    掲示板CGIについて質問です。 使おうとしているスクリプトはそのままアップロードすると書き込みした時間の表示が 「4/14 (Sun) 17:10」 のようになります。 これを 「2003 4/14 (日) 17:10:50」 のように年と秒まで加えたいのです。 それで後者のように表示される掲示板CGIを参考にしてみましたが、目立った違いはないように思え、どこをどう変更すれば年や秒まで表示されるようになるかわかりません。 思い当たる部分はこのあたりなのですが…。 ↓このように記述されています ************ $ENV{'TZ'} = "JST-9"; ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time); $year = sprintf("%02d",$year + 1900); $month = sprintf("%02d",$mon + 1); $mday = sprintf("%02d",$mday); if ( substr($month,0,1) == 0 ) { $month =~ s/0/ /; } if ( substr($mday,0,1) == 0 ) { $mday =~ s/0/ /; } $hour = sprintf("%02d",$hour); $min = sprintf("%02d",$min); $sec = sprintf("%02d",$sec); $youbi = ('Sun','Mon','Tue','Wed','Thu','Fri','Sat') [$wday]; $date_now = "$month/$mday ($youbi) $hour:$min"; ************ CGIに手を加えてレイアウトの変更くらいはいつもやっています。 もし書き換える方法がありましたら教えていただければと思います。 どうぞよろしくお願い致します。

    • ベストアンサー
    • CGI
  • perl-cgiのリネームについて

    Perl-CGIで ABCという、ディレクトリの中のファイルの名前を、ランダムな名前に変換したいのですがうまくいきません。 これを動作させるたびになぜか、どんどんファイルが減っていってしまいます。 どなたか、教えていただけないでしょうか? 宜しくお願い致します。 #!/usr/local/bin/perl print "Content-Type: text/plain\n\n"; $| = 1; my ($sec,$min,$hour,$mday,$mon,$year,$wno) = localtime(time); my ($nowtime) = sprintf("%02d_%02d_%02d_%02d_%02d_",$year+1900,$mon+1,$mday,$hour,$min,$sec); #ディレクトリのファイル個数を記録する $dir = "./ABC/"; # ← ディレクトリを変数にセットする opendir DIR, $dir; @files = grep { !m/^(\.|\.\.)$/g } readdir DIR; # ← 「.」 「..」 以外のファイルを取得 close DIR; srand; for (my $i = @files; --$i; ) { my $j = int rand ($i + 1); next if $i == $j; @files[$i, $j] = @files[$j, $i]; } $num = 0; use File::Copy; foreach(@files){ $getpath = "$dir"."$_"; if( copy($getpath, "$dir".$nowtime.$num++.'.dat') eq 1){ $num++; unlink($getpath);}else{print "Copy Error"; exit;} }

    • ベストアンサー
    • CGI
  • Perlの日付取得で月の表示がおかしい

    下記は、メールフォームCGIに書き込まれた日時などの情報をlog.cgiというファイルに書き出すスクリプトです。 2012/01/04 21:05:45 のような感じで、日付が刻まれるのですが、このうち月の部分がどの月に処理を行ってもいつも01になってしまうのですが、当方直し方がわかりません。 下記が実際の記載箇所です。4行目がおかしいのだと思いますが、どなたかお分かりの方、教えていただけないでしょうか。 my $path = "log.cgi"; my $ip = $ENV{'REMOTE_ADDR'}; ($sec, $min, $hour, $mday, $month, $year, $wday, $stime) = localtime(time()); my $time = sprintf("%04d\/%02d\/%02d %02d\:%02d:%02d", $year + 1900, $mon + 1, $mday, $hour, $min, $sec); my $message = $in{'メッセージ'}; $message =~ s/\r\n/ /g; $message =~ s/\n/ /g; if (open(FOUT, ">> $path")) { print FOUT "$time\t$ip\t" . $in{'お名前'} . "\t" . $in{'E-mail'} . "\t" . $message . "\r\n"; close(FOUT); } よろしくおねがいいたします。

    • ベストアンサー
    • Perl
  • 先月(YYYYMM)の生成方法

    言語は問いません。 先月をYYYYMM形式の文字列で得るクールな方法ってありますか? Perlで以下のように書けば正しく動きますが、なんかダサイ気がします。 my ($sec, $min, $hour, $mday, $mon, $year) = localtime ; $year -= 1 if $mon == 0; $mon = '12' if $mon == 0; $yearmonth = sprintf("%4d%02d", $year+1900, $mon); よろしくお願いします。

  • CGIについて(時間表示)

    CGI初心者ですが、掲示板を作成中です。投稿するたびにメッセージの投稿時間がすべて現在時刻に書き換わります。 メッセージ毎に時間表示させたいのですが、いかのプログラムのどこを変更すればよいのでしょうか?宜しくお願いいたします。 # 時間処理 sub totime { ($sec,$min,$hour,$mday,$month,$year,$wday,$yday,$isdst) = localtime(time); $year +=1900; $month++; $year = sprintf("%04d", $year); $month = sprintf("%02d", $month); $mday = sprintf("%02d", $mday); $hour = sprintf("%02d", $hour); $min = sprintf("%02d", $min); $sec = sprintf("%02d", $sec); $date = "$month/$mday $hour:$sec"; }

    • ベストアンサー
    • CGI
  • [error] [client ---- ] Argument

    初心者で http://oshiete1.goo.ne.jp/qa5056638.html で質問した者です。もうひとつ、お願いします。 Apache の error.log に [error] [client ---- ] Argument "..." isn't numeric in addition (+) at ... 0001.cgi line 85., と表示されるのを、防ぐ方法をお教えください。 ↓このようにしています。 open(FILE, '<+score.txt') or die "$!"; my @data = <FILE>; close(FILE); my $data2 = $data[0] +1;#------------- line85 open(FILE, '>+score.txt') or die "$!"; print FILE $data2; print FILE (",問題番号,$num,$year年$mon月$day日 $hour時$min分$sec秒\n"); print FILE @data; close(FILE); print "<font size=+1>今日 "; print "<font color=magenta>$data2</font color>";print "回 正解解答をしました --- </font size> "; 1時間に、0001.cgiと同じように書かれれたファイル約100個に、約40人がアクセスします。Apache の error.log が、すぐ大きくなってしまいます。どうか、よろしくお願いします。

    • ベストアンサー
    • Perl
  • perl qw(aaa bbb ccc)[$hoge]のような記述

    my($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst) = localtime(time); $wday = sprintf("%s", qw(Sun Mon Tue Wed Thu Fri Sat)[$wday]); 2行目のsprintfですが、qw(Sun Mon Tue Wed Thu Fri Sat)[$wday]はどのようなことが行われているのでしょうか? sprintf("%s", "hello world!");みたいな基本的なものならsprintfの使い方はわかります。ですが、qw(aaa bbb ccc)[$hoge]のような記述についてがわかりません。 上記の例でいえば、どういう結果になるのかはわかるのですが、どういう過程で代入されているのかがわかりません。 qw(Sun Mon Tue Wed Thu Fri Sat)[$wday]という書式はどういうことが行われているのか教えてください。よろしくお願いします。

    • ベストアンサー
    • Perl
  • MFC/C++ sprintf の代わりに <<

    昔VC6でMFC/C++を少しかじったことのある者です。 この度Visual Studio 2010でMFC/C++をやってみようということになりました。 昔作った古いコーディングを参考に、よりC++らしい書き方に改めようとしています。 現在時刻を名前にしたファイルを作成する際、 ファイル名をこれまでは sprintf() を使って、   char szFileName[11];   sprintf(szFileName, "%02d%02d%02d.txt", hour, min, sec);   (*)hour, min, sec のそれぞれに、時, 分, 秒の値が格納されているとする。 ように作っていたのですが、これを iostream な書き方に改めています。 このとき、   xxx << setfill('0')     << setw(2) << hour     << setw(2) << min     << setw(2) << sec     << ".txt" のようにするだろうことは分かったのですが、 恥ずかしながら、この xxx の定義の仕方(変数の型)が分かりません。 ウェブでいろいろ調べてみたのですが、 サンプルコードのほとんどが cout に出力していて、 変数に格納する方法が分かりませんでした。 初歩的な質問ですみませんが、よろしくお願いします。

  • PerlのCGIでこの期日判定方法は正しいですか?

    指定日の23時59分59秒以前にアクセスすると before.pdf を表示、翌0時00分00秒からは after.pdf を表示させるためのジャンプ台にするCGIを作ろうとしているのですが、アクセスした日時が指定日の23時59分59秒以前かどうかを判別する理論設定が下記の方法で合っているか心配です。 この例では今月末までは before.pdf を表示するという設定のつもりですが、論理に穴があって思いもよらず6月中にも after.pdf を表示してしまうケースがあったり7月になってからも before.pdf を表示してしまうケースが発生しないでしょうか? もし書き方が誤っていましたら添削して頂けるとありがたく存じます。 どうかよろしくお願い致します。 #!/usr/bin/perl use strict; use warnings; # アクセス時刻の取得 my ($sec, $min, $hour, $mday, $mon, $year) = localtime(time); # localtime関数の調整 $year += 1900; $mon += 1; # アクセス日時に応じたファイルにジャンプ my $file_name; if ($year <= 2023 && $mon <= 6 && $mday <= 30 && $hour <= 23 && $min <= 59 && $sec <= 59) { $file_name = "before.pdf"; } else { $file_name = "after.pdf"; } # ヘッダー出力およびリダイレクト print "Content-Type: text/html\n"; print "Location: $file_name\n\n";

    • ベストアンサー
    • Perl

専門家に質問してみよう