- ベストアンサー
以下の関数の解説お願いします。
Perl初心者のため、stdio.plにある この関数のやっていることがよく分からず困っています。 sub searchString #($str, $key, $mhmode, $lc, $z2h, $k2h, $igmark) { local($str, $key, $mhmode, $lc, $z2h, $k2h, $igmark) = @_; local($once, $from, $to); #static $key2, $key3; return 0 if ($str eq "" || $key eq ""); if ($key eq $key2) { $key = $key3; $once = 1; } else { $key2 = $key; } if ($jcode'version) { if ($k2h) { $from = 'アイウエオカキクケコサシスセソタチツテトナニヌネノハヒフヘホマミムメモヤユヨラリルレロワヲンガギグゲゴザジズゼゾダヂヅデドバビブベボパピプペポゐゑァィゥェォャュョッ'; $to = 'あいうえおかきくけこさしすせそたちつてとなにぬねのはひふへほまみむめもやゆよらりるれろわをんがぎぐげござじずぜぞだぢづでどばびぶべぼぱぴぷぺぽヰヱぁぃぅぇぉゃゅょっ'; } if ($z2h) { $from .= '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz+-=_|*!?”#$¥%&@:;'; $to .= '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz+-=_|*!?"#$\%&@:;'; } if ($igmark) { $from .= '-ー・/_ '; $to .= '------'; } if ($from) { &jcode'tr(*str, $from, $to); &jcode'tr(*key, $from, $to) if (!$once); $str =~ tr/-_\///d; $key =~ tr/-_\///d; } } if ($lc) { $str =~ tr/A-Z/a-z/; $key =~ tr/A-Z/a-z/ if (!$once); } $key3 = $key; if ($mhmode == 5 || $mhmode =~ /^BOOLEAN$/i || $mhmode =~ /^BLN$/i) { local($i) = 0; local(@str, $eval); $key =~ s/ +AND +/ & /gi; $key =~ s/ *NOT +/ ! /gi; $key =~ s/ +OR +/ | /gi; $key =~ s/\( +/(/g; $key =~ s/ +\)/)/g; foreach (split /( & | \| )/, $key) { $str[$i] .= $_; $i ++ unless ($_ eq ' & ' || $_ eq ' | ') } for ($i = 0; $i <= $#str; $i ++) { local($option, $open, $close, $find, $not, $key); $key = $str[$i]; if ($str[$i] =~ /^( & | \| )/) { $option = substr $key, 0, 3; $key = substr $key, 3; } $open = $1 if ($key =~ /^(\(+)/g); $close = $1 if ($key =~ /(\)+)$/g); $key =~ s/\(|\)//g; if ($key =~ /^ *! +/) { $key =~ s/^ *! +//g; $not = 1; } $find = index($str, $key) >= 0 ? 1 : 0; $find = $find ? 0 : 1 if ($not); $eval .= "$option$open$find$close"; } $eval =~ s/ & /*/g; $eval =~ s/ \| /+/g; return (eval $eval >= 1) ? 1 : 0; } elsif ($mhmode == 4 || $mhmode =~ /^NOR$/i) { foreach (split / +/, $key) { return 0 if (index($str, $_) >= 0); } return 1; } elsif ($mhmode == 3 || $mhmode =~ /^EOR$/i) { local($flag) = 0; foreach (split / +/, $key) { if (index($str, $_) >= 0) { return 0 if ($flag); $flag = 1; } } return $flag ? 1 : 0; } elsif ($mhmode == 2 || $mhmode =~ /^OR$/i) { foreach (split / +/, $key) { return 1 if (index($str, $_) >= 0); } return 0; } elsif ($mhmode == 1 || $mhmode =~ /^NAND$/i) { foreach (split / +/, $key) { return 1 if (index($str, $_) == -1); } return 0; } else { foreach (split / +/, $key) { return 0 if (index($str, $_) == -1); } return 1; } } これを呼び出しているのが、別ファイル内の以下の部分です。 foreach(@datafile){ if($datafile[0] eq $_){ next; } # 1行目は項目名なので next if($param{'query_word'}){ unless(stdio::searchString($_, $param{'query_word'}, $param{'query_search_type'}, 1, 1, 1, 1)){ next; } } push(@search_file,$_); } datafileは 名前,住所,電話番号, 吉田,東京都渋谷区,03xxxxxxxx, といったデータファイルです。 よろしくお願いします。
- みんなの回答 (2)
- 専門家の回答
関連するQ&A
- 解析機能の拡張について
おはようございます。いつもお世話になっています。 今回は解析機能の拡張についてお聞きしたいと思います。 解析機能については、かんたん作成.comさんのcgiをお借りしました。 http://www7a.biglobe.ne.jp/~wwwwww/analyzer/ これをベースに、検索ワードの集計機能を追加しようと思っております。 word1、word2に検索ワードの表示・分割がありますが、新たにword3を設けて分割されたものを集計し、表示する処理をしたいです。 集計については、前回までで教えていただいた正規表現を用いて自ら組んでみたのですが、変数が一致していないせいか上手く表示できません。 以下に検索ワードを処理しているプログラムを記載します。 elsif($FORM{'mode'} eq "word1" or $FORM{'mode'} eq "word2" or $FORM{'mode'} eq "word3") { #検索ワード my ($n, $pair, $word); if($referer =~ /\?/) { my ($url, $query) = split(/\?/, $referer); for($n = 0 ; $n < @search ; $n++) { if($url =~ /$search[$n][1]/) { foreach $pair (split(/&/, $query)) { my ($key, $value) = split(/=/, $pair); if($key eq $search[$n][2]) { $word = $value; last; } } last; } } if($word) { $word =~ tr/+/ /; $word =~ s/%([0-9a-fA-F][0-9a-fA-F])/chr(hex($1))/eg; if($FORM{'mode'} eq "word1") { ++$freg{$word}; } elsif($FORM{'mode'} eq "word2") { my $word2; $word =~ s/\x81\x40/ /g; foreach $word2 (split(/\s+/, $word)) { if($word2) { ++$freg{$word2}; } } } #=====================================================================EDIT elsif($FORM{'mode'} eq "word3") { my %word_of = map {$_ => 0} %freg; foreach my $search_key ( keys %word_of ) { foreach my $word ( keys %word_of ) { $word_of{$search_key}++ if $word =~ /$search_key/; } } foreach ( sort ( keys %word_of ) ){ print "<table><tr><td>「$_」 </td><td> $word_of{$_} 件</td></table>\n"; } } #=====================================================================END } } } } word3の項目が現在私が編集している部分です。 プログラム全体を通して、私自身が望む動作を可能とする部分の追加は行ったと思うのですが、見落としている点があるかもしれません。 また前述したように、変数が一致していないのかもしれません。 おかしな点に気づかれたら、お手数ですがお教え願えますか。 もしかしたら初歩的なミスをしているかもしれませんが、よろしくお願いいたします。 不明な点などございましたら、随時対応します。 ここでは書ききれないため、現在編集中のcgiファイルを添付データとして貼り付けておきます。
- 締切済み
- Perl
- Smartyでインクリメント
Smartyで以下のような処理がしたいのですがうまくいきません・・・(横にセルを5コ並べた後に改行したい) どのように記述したらよいか教えて頂けますでしょうか。 <table> <tr> {$i = 0} {foreach item=item_list from=$item_list} <td>{$item_list.hoge|escape}</td> {$i = $i + 1} {if $i mod 4 eq 0} </tr><tr> {/if} {/foreach} </table>
- ベストアンサー
- PHP
- CGIでhtmlページを表示する
連日質問させていただいています。 CGI超初心者です。 htmlファイルにラジオボタンを設置し、 Aを選んだらhttp://www.a.html、 それ以外を選んだらhttp://www.b.html というサイトを開くようなCGIを作成したいです。 以下のようにやってみたのですがうまくいきません。 どのように修正したらいいでしょうか? #============================================ if ($ENV{'REQUEST_METHOD'} eq "POST") { read(STDIN, $str, $ENV{'CONTENT_LENGTH'}); } else { $str = $ENV{'QUERY_STRING'}; } foreach $i (split('&', $str)) { $i =~ tr/+/ /; $i =~ s/%([0-9a-fA-F][0-9a-fA-F])/pack("C", hex($1))/eg; ($t1, $t2) = split('=', $i); $FORM{"$t1"} = $t2; } $q1 = $FORM{'radio'}; print "Content-Type: text/html; charset=Shift_JIS\n\n"; print "<html>\n"; print "<head></head>\n"; print "<body>\n"; if ($q1 eq "A") { print "Location: http://www.a.html\n\n"; } else { print "Location: http://www.b.html\n\n"; } print "</body>\n"; print "</html>\n"; exit; #============================================ 上記のようにすると、以下のように、ただ文字が表示されてしまいます。 Location: http://www.a.html #============================================ if ($ENV{'REQUEST_METHOD'} eq "POST") { read(STDIN, $str, $ENV{'CONTENT_LENGTH'}); } else { $str = $ENV{'QUERY_STRING'}; } foreach $i (split('&', $str)) { $i =~ tr/+/ /; $i =~ s/%([0-9a-fA-F][0-9a-fA-F])/pack("C", hex($1))/eg; ($t1, $t2) = split('=', $i); $FORM{"$t1"} = $t2; } $q1 = $FORM{'radio'}; print "charset=Shift_JIS\n\n";←★ print "<html>\n"; print "<head></head>\n"; print "<body>\n"; if ($q1 eq "A") { print "Location: http://www.a.html\n\n"; } else { print "Location: http://www.b.html\n\n"; } print "</body>\n"; print "</html>\n"; exit; #============================================ ★部分が悪いのかなぁと思い、上記のように修正してみたり、 (Content-Type: text/html; を削除してみました) ★部分を全部削除してみると Internal Server Error となってしまいます。 よろしくお願いいたします!
- ベストアンサー
- CGI
- リクエストパラメタを一括置き換え
リクエストパラメタを一括置き換え if( $ENV{'REQUEST_METHOD'} eq "GET" ) { $buffer = $ENV{'QUERY_STRING'}; } else { read( STDIN, $buffer, $ENV{'CONTENT_LENGTH'} ); } %req_params = map { /([^=]+)=(.+)/ } split /&/, $buffer; 上記のように書いていて、リクエストされたものを置き換える時は次のように一個一個書いています。 $req_params{name} =~ s/&/&/g; $req_params{mail} =~ s/&/&/g; $req_params{url} =~ s/&/&/g; このリクエストされたパラメタを一括で置き換えするにはどうすればいいのでしょうか? 例えば、上記の書き方で以下のようなことをしたいです。よろしくお願いいたします。 if ($ENV{'REQUEST_METHOD'} eq "POST") { read(STDIN, $buf, $ENV{'CONTENT_LENGTH'}); } else { $buf = $ENV{'QUERY_STRING'}; } foreach ( split(/&/, $buf) ) { ($key, $val) = split(/=/); $val =~ tr/+/ /; $val =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("H2", $1)/eg; $val =~ s/&/&/g; $req_params{$key} .= "\0" if (defined($req_params{$key})); $req_params{$key} .= $val; }
- ベストアンサー
- Perl
- フリーCGI ラジオボタンの改行についてです。
色々調べましたが、どうしても分からなかった為質問させて頂きます。 http://cgikon.com/search/detail.php3?cgi_id=308 こちらのフリーCGIをお借りして、アンケートを作成することになりました。 質問は、ほぼラジオボタンによる3択です。 デフォルトだと、ラジオボタンは横並びになっているのですが 質問内容が長過ぎるため、見づらくなってしまいます。 その為、ラジオボタンを添付画像のように改行したいと思っております。 おそらく、下記のどこかを変更すればいいとは思うのですが 分かりませんでした…。 # アンケート質問の表示 my($number) = 0; foreach (@question) { ($qtype,$qname,@column) = split(/\t/); next if($qname eq ""); $number++; $key = "Q".$number; print qq! <TR> <TD NOWRAP VALIGN="top"><B>【質問$number】</B></TD> <TD>$qname</TD> </TR> <TR> <TD> </TD> <TD> !; if($qtype =~ /LISTBOX/i) { print qq!<SELECT NAME="$key" SIZE=1>!; foreach (@column) { next if(!$_); print qq!<OPTION VALUE="$_">$_!; } print qq!</SELECT>!; } elsif($qtype =~ /RADIO/i) { foreach (@column) { next if(!$_); print qq!<INPUT TYPE="radio" NAME="$key" VALUE="$_">$_!; } } elsif($qtype =~ /TEXTAREA/i) { print qq!<TEXTAREA NAME="$key" COLS=50 ROWS=5></TEXTAREA>!; } elsif($qtype =~ /TEXTBOX/i) { print qq!<INPUT TYPE="text" NAME="$key" VALUE="" SIZE=50>!; } print qq! </TD> </TR> !; } 配布元のサイト様が今月末で閉鎖される為 それに伴い、個別でカスタマイズなどの依頼対応も出来ない状態です。 申し訳ございませんが、どなたか詳しい方 ご教授頂ければ幸いです。どうか宜しくお願い致します
- ベストアンサー
- CGI
- ホームページから意見を送るsendmailのcgiスクリプト
表題のようなスクリプトを使っているのですが、 普通は特に問題ないのですが、「http://」などから始まる URLのみを書き込んで送ると、空メール(何も記載されない)となって 届いてしまいます。どこがおかしいのかわかりません。 以下のようなスクリプトです。 @pairs = split(/&/,$buffer); foreach $pair (@pairs) { ($name,$value) = split(/=/,$pair); $value =~ tr/+/ /; $value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C",hex($1))/eg; $name =~ tr/+/ /; $name =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C",hex($1))/eg; &jcode'convert(*name,'sjis'); &jcode'convert(*value,'sjis'); if ($name eq 'to') { $to = $value; } if ($name eq 'from') { $from = $value; } if ($name eq 'subject') { $subject = $value; } if ($name eq 'body') { $body = $value; } } # cheack if ($from eq "") { $from = "unknown\@."; } if ($from eq " ") { $from = "unknown\@."; } # send mail &jcode'convert(*from,'jis'); &jcode'convert(*subject,'jis'); &jcode'convert(*body,'jis'); if (!(open(MAIL,"| $sendmail -t"))) { &error('システムエラー','メールの送信に失敗しました。'); } print MAIL "To: $to\n"; print MAIL "From: $from\n"; print MAIL "Subject: $subject\n"; print MAIL "Content-Type: text/plain; charset=iso-2022-jp\n"; print MAIL "$body\n"; close(MAIL); # view html &jcode'convert(*from,'sjis'); &jcode'convert(*subject,'sjis'); &jcode'convert(*body,'sjis'); $body =~ s/\r\n/\r/g; $body =~ s/\n/\r/g; $body =~ s/\r/<BR>/g;
- ベストアンサー
- CGI
- 画像ファイルパス名でのログファイルへの書き込み
CGI勉強中です。Kentさんのトピックスボードのサブルーチンを参考にさせていただいていますが、画像ファイル名パスのログファイルへの書き込みが、 <>画像拡張子<>横サイズ<>縦サイズ<>・・・・省略 <>.gif<>100<>100・・・・・・省略 なのですが、上の画像拡張子のみ書き込みされている部分を画像ファイルパス+ファイル名+拡張子という具合にログファイルへ書き込むにはどのようにしたらよいのでしょうか?アドバイス願います。 参考までにkentさんのサブルーチン sub upload { local($no) = @_; local($tail,$fnam,$macbin,$f,$i,$flag,$imgfile, $upfile,$length,$W,$H,$W2,$H2,@tail,@fnam,@name,@upfile); # 画像処理 $macbin=0; @tail=(); @fnam=(); @name=(); foreach (@in) { if (/(.*)Content-type:(.*)/i) { $tail = $2; $tail =~ s/\r//g; $tail =~ s/\n//g; push(@tail,$tail); } if (/.*name=\"(.*)\";.*filename=\"(.*)\"/i) { $fnam = $2; $fnam =~ s/\r//g; $fnam =~ s/\n//g; push(@fnam,$fnam); push(@name,$1); } if (/application\/x-macbinary/i) { $macbin=1; } } # ファイル形式を認識 $f=0; $i=0; @upfile=(); foreach (0 .. $#tail) { $i++; $flag=0; if ($tail[$_] =~ /image\/gif/i) { $tail=".gif"; $flag=1; } elsif ($tail[$_] =~ /image\/jpeg/i) { $tail=".jpg"; $flag=1; } elsif ($tail[$_] =~ /image\/x-png/i) { $tail=".png"; $flag=1; } if (!$flag) { if ($fnam[$_] =~ /\.gif$/i) { $tail=".gif"; $flag=1; } elsif ($fnam[$_] =~ /\.jpe?g$/i) { $tail=".jpg"; $flag=1; } elsif ($fnam[$_] =~ /\.png$/i) { $tail=".png"; $flag=1; } } if ($name[$_] eq "upfile$i") { $upfile = $in{"upfile$i"}; $imgfile = "$imgdir/$no-$i$tail"; } # アップロード結果 if ($flag) { $f++; } else { push(@upfile,("","","")); next; } # マックバイナリ対策 if ($macbin) { $length = substr($upfile,83,4); $length = unpack("%N",$length); $upfile = substr($upfile,128,$length); } # データ書込み open(OUT,">$imgfile") || &error("画像アップ失敗"); binmode(OUT); binmode(STDOUT); print OUT $imgfile; close(OUT); chmod (0666,$imgfile); # 画像サイズ取得 if ($tail eq ".jpg") { ($W, $H) = &j_size($imgfile); } elsif ($tail eq ".gif") { ($W, $H) = &g_size($imgfile); } elsif ($tail eq ".png") { ($W, $H) = &p_size($imgfile); } # 画像表示縮小 if ($W > $MaxW || $H > $MaxH) { $W2 = $MaxW / $W; $H2 = $MaxH / $H; if ($W2 < $H2) { $key = $W2; } else { $key = $H2; } $W = int ($W * $key) || 1; $H = int ($H * $key) || 1; } push(@upfile,($tail,$W,$H)); } return @upfile; }
- 締切済み
- Perl
- malloc関数(strtok関数の自作版)につきまして分からないこと
malloc関数(strtok関数の自作版)につきまして分からないことがあります。 以下のプログラムにmallo関数がフリーする最適な位置を明示しなさいといわれました。 文字が分離した時にfreeすると助言されたのですが いまいち理解できません・・・。 条件式の中で使用するともいわれていました。(おそらくif文・・・。) 色んな意見を参考にしたいので詳しい方助言のほうよろしくおねがいします。 なおプログラムはほかの箇所を変更したり、他の場所でもmalloc関数を使用することが認められています。 またfreeする場所はメイン関数ではなくあくまでもstrtok関数の中で宣言するようです。 よろしくお願いします。 #include <string.h> #include <stdio.h> #include <stdlib.h> main(){ char* s2 = ",/"; char* result; char* r1; char* r2; char* r3; char* r4; result = strtok("//123//,45/,678,9/","/,"); r1 = strtok(NULL, s2); r2 = strtok(NULL, s2); r3 = strtok(NULL, s2); r4 = strtok(NULL, s2); printf("%s\n",result); printf("%s\n",r1); printf("%s\n",r2); printf("%s\n",r3); printf("%s\n",r4); return; } char *strtok(char *s1, const char *s2) { int i,len; char *str1, *str2 , *str3; static char *tok ; static char* mstr; if(s1 != NULL) { str1 = s1; } else { str1 = tok; } str2 = str1 + strspn(str1, s2); /* strspnを利用 */ if (*str2 == '\0') { return (NULL); } len = 1; i = 0; while(*(str2 + i) != '\0'){ len++; i++; } mstr = (char*)malloc(sizeof(char)*len); if(mstr == (NULL)) { return 0; } i = 0; while(*(str2 + i) != '\0'){ *(mstr + i) = *(str2 + i ); i++; } *(mstr + i ) = '\0'; str3 = mstr + strcspn(mstr, s2); /* strcspnを利用 */ if (*str3 != '\0'){ *str3 = '\0'; str3 = str3 + 1; } tok = str3; return (mstr); }
- ベストアンサー
- C・C++・C#
- アンケートフォームに機能の付け加え。
ホームページ上で、訪問者からアンケートを採れるsendmailを使用した CGIを設置しています。ここに、訪問者から簡単な素材を提供して頂けるよう 以下のようなスクリプトに、小さなファイル(gif画像など)を 添付して送れるように機能を付け足したいです。 どうすればいいか、困っています。どうすればよいでしょうか? @pairs = split(/&/,$buffer); foreach $pair (@pairs) { ($name,$value) = split(/=/,$pair); $value =~ tr/+/ /; $value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C",hex($1))/eg; $name =~ tr/+/ /; $name =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C",hex($1))/eg; &jcode'convert(*name,'sjis'); &jcode'convert(*value,'sjis'); if ($name eq 'to') { $to = $value; } if ($name eq 'from') { $from = $value; } if ($name eq 'subject') { $subject = $value; } if ($name eq 'body') { $body = $value; } } # cheack if ($from eq "") { $from = "unknown\@."; } if ($from eq " ") { $from = "unknown\@."; } # send mail &jcode'convert(*from,'jis'); &jcode'convert(*subject,'jis'); &jcode'convert(*body,'jis'); if (!(open(MAIL,"| $sendmail -t"))) { &error('システムエラー','メールの送信に失敗しました。'); } print MAIL "To: $to\n"; print MAIL "From: $from\n"; print MAIL "Subject: $subject\n"; print MAIL "Content-Type: text/plain; charset=iso-2022-jp\n\n"; print MAIL "$body\n"; close(MAIL); # view html &jcode'convert(*from,'sjis'); &jcode'convert(*subject,'sjis'); &jcode'convert(*body,'sjis'); $body =~ s/\r\n/\r/g; $body =~ s/\n/\r/g; $body =~ s/\r/<BR>/g;
- 締切済み
- CGI
- sscanfでフォーマットに合っているかを調べるには。
今,Cの関数で0-9,A-Zの4文字以内の文字列かどうか を調べたいのですが, int main() { int i; char str[] = "ABCD" /* 調べたい文字列1 */ char str1[]= "ABC@" /* 調べたい文字列1 */ char str2[]= "ABCDE" /* 調べたい文字列1 */ char *p; p = str; /* ここをstr1,str2に変える */ if (strlen(p) != 4) printf("エラーです\n"); for (i = 0; i < 4; i++) { if (!isupper(p[i]) && !isdigit(p[i])) { printf("えらーです\n"); return EXIT_FAILURE; } } printf("すべてOKです\n"); return EXIT_SUCCESS; } というようにすれば,strとstr1とstr2がフォーマットに合うかわかるのですが,これをsscanfの正規表現を使用して実装したいのですが,可能でしょうか。 int main() { int ret; char str[] = "ABCD" /* 調べたい文字列1 */ char str1[]= "ABC@" /* 調べたい文字列1 */ char str2[]= "ABCDE" /* 調べたい文字列1 */ char *p; chat tmp[30]; p = str; ret = sscanf(p, "%4[0-9A-Z]", tmp); if (ret != 1) { printf("エラーです\n"); return EXIT_FAILURE; } printf("すべてOKです\n"); return EXIT_SUCCESS; } といしょうとするならば,str1のときは,@までのABCの文字列がとれて,retには1が帰ってきてしまいます。 なにか4文字以内ということを実装できる正規表現の使い方はあるのでしょうか? ちなみに sscanf(str, "%1[0-9A-Z]%1[0-9A-Z]%1[0-9A-Z]%1[0-9A-Z]", tmp1, tmp2, tmp3, tmp4) という以外でわかる方,よろしくおねがいします。
- ベストアンサー
- C・C++・C#