Perl コーディング初心者質問コーナー Part33
■ このスレッドは過去ログ倉庫に格納されています
0001nobodyさん
04/03/01 02:46ID:1GeWO7LH【投稿する際の注意】
質問するときは内容をよく吟味してから投稿してください。
「コマンドの意味がわかんない」とかはマニュアル見ましょう。
回答者さんは何でも屋じゃありません。
1: 自分はこう言う事がしたい。
2: それでこんな風にやってみたが・・・
3: こんなエラーが出て上手く行かなかった。
最低でも1と3が無いと誰も答えられないよ。
ソース貼る時は、全角スペースでインデント忘れずに。
良い回答は良い質問から。一緒に勉強しましょう。
過去ログやお勧めサイトは >>2-10
0358nobodyさん
04/03/11 23:05ID:???えーとですね、
「3:こんなエラーが出て上手く行かなかった」というのは、
「ダメだった」と書かれてもそれじゃどうしようもなく、
ダメだったときのエラーメッセージなりログなりを提出せよ、
と、そういうことなんです。
それがないと、何が起きているかわからない。
会社の後輩でも、毎回「まず error_log を見てから俺に相談しろ」と口を酸っぱくして言ってるのに
全然憶えないやつがいるんだけど、なんでみんなああなのかね。
0359353
04/03/11 23:08ID:AiFNJNW+おそれいります。
文字列'ne'を含まないアドレスについては、うまくいくという意味です。
@のエスケープに関しては、すべて行っています。
0361351
04/03/11 23:23ID:AiFNJNW+すいません。
言い忘れましたが、Tera Padというテキストエディタでみると、
'ne'のぶぶんがprintと同じようにボールド体で表示されるのです。
そこで、\n\eとしてみたところ、ボールド体ではなくなりましたが、それで実行すると、
文字列'ne'以下が省略されたかたちでメールが送られた、というメッセージがでました。
どう考えたらいいのでしょうか。
0362353
04/03/11 23:43ID:???0364nobodyさん
04/03/12 04:58ID:SsTHKK/b以下のようなときにもっといい方法無いでしょうか。
$str = '200402';
($year,$month) = (substr ($str,0,4),substr ($str,4,2));
0365nobodyさん
04/03/12 05:03ID:???Tera Pad云々ということはソースに直接メアド入れてるんでしょ?
その付近のソースを貼ったらわかるんじゃないの?
てかそのアドレスを代入した変数を正規表現でチェックしてる?
だとしたらそこがあやしいよーな
0367nobodyさん
04/03/12 05:26ID:???$str = '200402';
$str =~ /^(\d{4})(\d{2})$/;
print $y = $1;
print $m = $2;
0368nobodyさん
04/03/12 05:31ID:???>>364
TMTOWTDI.
# substr
my($year, $month) = (substr($str, 0, 4), substr($str, 4, 2));
# unpack
my($year, $month) = unpack 'A4A2', $str;
# パターンマッチ
my($year, $month) = $str =~ /^(\d{4})(\d{2})/;
# 置換1 (非破壊)
(my $year = $str) =~ s/(\d{2})$//;
my $month = $1;
# 置換2 (非破壊)
my $month;
(my $year = $str) =~ s/(\d{2})$/($month = $1, '')[1]/e;
# 回りくどい方法
my @tmp = split //, $str;
my $year = join '', splice @tmp, 0, 4;
my $month = join '', @tmp;
0370369
04/03/12 05:33ID:???0371364
04/03/12 05:36ID:???それだと弄る箇所がかなり多くなってしまうんで、
スマートに切り分ける方法があるのならな。と思って質問してみました。
やっぱり_で区切っておいてsplitの方がよさげなんで、そっちで行きます。
わざわざ有難うございました。
0373351
04/03/12 08:25ID:J1fEY9awmailtoに代入されたアドレスのうち、****\@jcom.home.ne.jpだけにエラーが生じます。
時間がないので失礼します。
#$mailto = "****\@taurus.livedoor.com";
#$mailto = "****\@jcom.home.ne.jp";
#$mailto = "****\@****.org";
$mailto = "****\@yahoo.co.jp";
jcode::convert(\$name, "jis");
jcode::convert(\$comment, "jis");
open(MAIL, "|$sendmail $mailto");
print MAIL "Subject:comments and questions\n";
print MAIL "Reply-To: $in{'mail'}";
print MAIL "\n$in{'comment'}";
close(MAIL);
0374nobodyさん
04/03/12 09:21ID:???#$mailto = "****\@$jcom"; とかでも無理?
0375nobodyさん
04/03/12 11:25ID:S7woz7f4出したいのですが情報操作目的の、普通ではあり得ない価格報告を
平均価格を計算する時に使ってしまうと平均価格が狂ってしまうのでそれを避けたい
のですが良い計算方法が浮かびません。
10 + 20 + 20 + 30 / 4 = 20 #正常
10 + 20 + 20 + 3000 / 4 = 762.5 #異常
こういう事態を避けたいのです。
perlコーディングというより数学計算式の問題のような気もするのですが
該当スレが見つからなかったのでここに書かせて頂きました。
どなたかよいアドバイス頂けないでしょうか?
0376nobodyさん
04/03/12 11:46ID:???perlのコーディングの話ではないですね。
標準偏差使えばいいんじゃないかと思うけど、この板で話続けるなら
△▲ WebProg 初心者の質問 Part8 ▼▽
http://pc2.2ch.net/test/read.cgi/php/1078568723/
0379nobodyさん
04/03/12 12:14ID:???小数点第一位で四捨五入を行なうときには、
$hoge = int($hoge + 0.5);
とすれば整数部分のみが取得できますが、
小数点第二位で四捨五入を行なうときには、
($hoge + 0.05);
の他に、どのような記述を追加すればいいのでしょうか。
0380nobodyさん
04/03/12 12:47ID:???# パーセンテージを算出する
$percent = ($count / $total * 100);
print <<"EOF";
<IMG src="グラフ.gif" width="グラフの長さ" height="10"> $percent</TD>
EOF
こうある場合で、小数点第二位で四捨五入した値を$percentに表示したいのです。
0381nobodyさん
04/03/12 13:12ID:???0382nobodyさん
04/03/12 14:27ID:???再帰とかいろいろ調べてるのですが、いまいちでして。。
0383遙皇 ◆HEHARUKAoo
04/03/12 14:55ID:???皆さんが普段使っているものやおすすめのものを教えてください。
socketから書くの('A`)ノ マンドクセ
0385nobodyさん
04/03/12 15:19ID:???http://pc2.2ch.net/test/read.cgi/php/997829243/ あたりが妥当だろう
0387nobodyさん
04/03/12 16:38ID:???0388nobodyさん
04/03/12 16:54ID:???【PHP】質問スレッド Part15
http://pc2.2ch.net/test/read.cgi/php/1078592587/ あたりが妥当だろう
0389nobodyさん
04/03/12 17:13ID:???$pkg2->get_hash_ref($hashref);
package pkg2;
..
sub get_hash_ref{
my $self = shift;
$self->{'hashref'} = shift;
..
}
のように渡した時、get_hash_ref()内で
while(my($key, $value) = each %{$self->{'hashref'}}){
${$self->{'hashref'}}{$key} = 0 unless $value;
}
とかやっても0が代入されないようなのです。
何が悪いのでしょうか。
0390nobodyさん
04/03/12 17:24ID:???0392nobodyさん
04/03/12 19:48ID:???こんなでも動くけど。
my %hash = (a=>1, b=>undef, c=>3, d=>4, e=>undef);
my $pkg2 = pkg2->new();
$pkg2->get_hash_ref(\%hash);
while(my($key, $value) = each %hash){
print $key, ' => ', $value, "\n";
}
exit;
package pkg2;
sub new
{
return bless {}, shift;
}
sub get_hash_ref
{
my $self = shift;
$self->{'hashref'} = shift;
while(my($key, $value) = each %{$self->{'hashref'}}){
${$self->{'hashref'}}{$key} = 0 unless $value;
}
}
> ${$self->{'hashref'}}{$key} = 0 unless $value;
これが通るのが謎。
$self->{'hashref'}->{$key} = 0 unless $value;
こうするのがいいっしょ。
0393nobodyさん
04/03/12 20:12ID:hneCqJMtWindows XPの場合cookieファイルはどこにあるんでしょうか?
98SEのときと保存の仕方が違うようなのです。
0394330
04/03/12 20:50ID:???いろいろ検索してみたのですが、'C'にも対応したコードがわかりません。
上記のコードはperlメモの写しなのですが、世間じゃ大概urlエンコードには
この方式を利用していますよね?手持ちの本も見てみたのですが、
これも'C'にはマッチしないものでした。
ということは大半のperlスクリプトに'気'を渡したら誤動作を起こすということでしょうか?
0395nobodyさん
04/03/12 21:03ID:???もうperlコーディングの話題じゃないわけだ。
お前は2chにアクセスするとき
http://%32%63%68%2e%6e%65%74/%32%63%68%2e%68%74%6d%6c
でアクセスする気か?
0397nobodyさん
04/03/12 21:32ID:???この書き方って、あんまり印象良くないね。
周知の事実なんだが、自分が、さも今発見したっていうか。
そんなもん、知らない方がおかしいっての。
98SEからPC触ってるんだったら、この何年、何やってたんだって話だよ。
少しは自分で調べることを覚えないとな。
いつまでたっても、初心者じゃカコワルイ。
0398nobodyさん
04/03/12 21:52ID:???-------------------------------------------------------
こ こ ま で 釣 り 堀
0399nobodyさん
04/03/12 22:00ID:???Perlコーディングと関係ない質問はスレ違いということで。
△▲ WebProg 初心者の質問 Part8 ▼▽
http://pc2.2ch.net/test/read.cgi/php/1078568723/l50
へどうぞ。
0400393
04/03/12 22:01ID:???そのクッキーファイルの保存状況を確認しようとしたら見つからなかったんです。
とりあえずcookieでCドライブに検索かけて
cookieがあるフォルダまでは到達して探してたんだけど
目的のファイルが見つからなくてもしかしたら別のフォルダもしくは
特殊な方法で保存してあるのかと思ったけどようやく発見しました。
0401nobodyさん
04/03/13 01:09ID:i+mpAF5R$logno = 1
$num = 2
$ext = ".txt"
だとして、$temp = "$logno_$num$ext" とすると 2.txt と帰ってきてしまいます。
手持ちの入門書(CGI&Perlポケットリファレンス)で見る限りはアンダーハイフンを
エスケープする必要があるという記述は見つけられないのですが、
$temp = "$logno\_$num$ext" としたらきちんと 1_2.txt と帰ってきました。
これはどういう理屈なのでしょうか。
0402nobodyさん
04/03/13 01:23ID:???0403nobodyさん
04/03/13 01:26ID:???${logno}_$num$ext
0405393
04/03/13 12:47ID:???0406nobodyさん
04/03/13 17:17ID:0t1k16srmy %NEW;
my $maxno
だと正常動作するのですが、
my %NEW,$maxno;
だと正常動作しません。
こういうもんなんでしょうか?
どっかで、こういう例を見たような気がするのですが・・・。
0409nobodyさん
04/03/13 20:27ID:3lH9+FV2単位はすべて円です
Windows日本語製品版です。Macもあります。
Office 2003 Pro 10000
Windows XP Pro 4000
Windows 2000 Pro 4000
Windows 2003 Server Enterprise 15000
FrontPage 2003 4000
Acrobat6.0 Pro 7000
Illustrator 10.0 10000
Illustrator CS 10000
PageMaker 7.0 7000
Photoshop 7.0 10000
Photoshop CS 10000
Premiere Pro 10000
Flash MX 2004 5000
期間限定で販売します。希望品,郵便番号,送り先住所,氏名,合計金額を記してお申し込みください。すべてユーザー登録できません。ほかにも商品(Win,Mac)ございます。
リスト希望の方は「リスト希望」のタイトルでメールください。
ご注文はここ→ [email protected]
広告希望はコチラ [email protected]
メール専門広告代理店 本気と書いて大マジっス!広告
0410nobodyさん
04/03/14 10:20ID:YQY2sb9a書いてみたのですが疑問があります。
use strict;
print "content-type: text/html\n\n";
print $a;
exit;
$aは宣言されていないのになぜかエラーがでません。
$abに変えるとエラーがでました。これはなぜなのでしょうか?
0411nobodyさん
04/03/14 10:23ID:???0412nobodyさん
04/03/14 10:30ID:YQY2sb9a0413nobodyさん
04/03/14 12:54ID:YQY2sb9a今作ってるBBSのタイトルや文字色などの設定はsetting.cgi
というものに書かれています。
$title = 'BBS';
$color = '#555555';
のように
それを呼び出して変数をセットしていたのですが、use strictを
使った場合はmainパッケージを指定して
$main::title
のようにしないとだめなのでしょうか?
使うたびにいちいち$main::
と記述するのが面倒なのですが・・・
0414nobodyさん
04/03/14 12:57ID:2Zg8YvJb>122 :root ★ :04/03/13 21:30 ID:???
>こっちにも貼っておこう。
>916 名前:root ★[sage] 投稿日:04/03/13 21:28 ID:???
>・同時に動くread.cgi数を制限するディレクティブorモジュール
>・負荷(LA)を見てCGI起動を制限するディレクティブモジュール
>
>があったら、誰か教えてください。
http://qb3.2ch.net/test/read.cgi/operate/1078921755/829
http://qb3.2ch.net/test/read.cgi/operate/1078921755/831
http://qb3.2ch.net/test/read.cgi/operate/1078921755/916
0418die($/);
04/03/14 14:24ID:ntUNbT3i気になって朝も起きれません
0419nobodyさん
04/03/14 14:43ID:???0420die($/)
04/03/14 14:48ID:ntUNbT3i0421nobodyさん
04/03/14 17:11ID:???0422nobodyさん
04/03/14 18:06ID:???既存のスクリプトを改造しているのですが、以下のようなことをしようと
思っています。
1)フォームより***.txtといったようなファイルを送信する
2)入力されたファイルを解析して結果を表示する
・・・というものです。
フォームにテキストそのものを書き込む方法ならその値を読み込む
方法なら簡単だと思うのですが・・・
フォーム入力から例えば***.txtというファイルを送信した場合に
これを一旦任意のディレクトリにアップロードして、スクリプト内で
ファイルをopenして処理する以外に方法はないのでしょうか?
0423413
04/03/14 19:33ID:MYhrucqause strict;
としたあとに、
my $val = 10;
print "Content-type: text/html\n\n";
print $val;
exit;
としたところ動きました。どうもありがとうございました。
0424nobodyさん
04/03/14 19:42ID:???>これを一旦任意のディレクトリにアップロードして、スクリプト内で
>ファイルをopenして処理する以外に方法はないのでしょうか?
どうもないらしい。少なくとも俺は知らん。
CGI.pmのドキュメントを読めばわかると思うが、
同じように一時ファイルに保存する分、それがセキュリティの穴になりうる可能性があるとのこと。
まあ、さっと保存してさっと処理してさっと消して、穴になる確率を極力減らす努力をしよう。
0425nobodyさん
04/03/14 19:45ID:wZU93kf10427422
04/03/14 20:14ID:???ありがとうございます。
必死にぐぐってみているのですが、どうもそれらしい資料が見当たらない
のはそういう理由なのでしょうね。
>>424さんいアドバイスいただいたようにセキュリティの穴を作らないよう
素直にテンポラリファイルを作って対処したいと思います。
何分perlの勉強を始めたばかりでわからないことばかりですがひとつひとつ
問題を乗り越えていきたいと思います。
どうもありがとうございました。
0428422
04/03/14 20:21ID:???考えていたのは送信したpostで受けたファイルをいちいち保存しないでそのまま
メモリ上に展開して解析、値を返す、、、ようなことを考えていました。
もっと精進します。
0429nobodyさん
04/03/14 22:25ID:???multipart を自力でデコードすれば原理的に不可能な話じゃないだろう
CGI.pm の man に書いてあるのは、
「CGI.pm はテンポラリファイルを作るので盗聴の恐れもあるんだよ」ということで、
本来はテンポラリファイルを作らず自力でデコードする方がセキュリティは高い。
なんだが、自力でデコードするのがめんどいので、
たいていみんな「盗聴されてもいいやー、どーせuploaderだしぃ」とか妥協して
CGI.pm に頼ってしまうわけだ。
自力でデコードするなら、
ttp://www.hk.airnet.ne.jp/~ahero/cgi/cgiex11.html
あたりを参考にしてみては。
0431nobodyさん
04/03/15 00:31ID:???それはともかく、アップローダーとかなら見られても問題ないが、
そうでないなら自力でデコードするべきということだな。
つーか何でCGI.pmが危険を承知でそんな設計になってるんだ?
0433nobodyさん
04/03/15 01:07ID:???0434nobodyさん
04/03/15 01:15ID:???外から不可視のディレクトリ内に作らせるようには出来ないのかい。
0435nobodyさん
04/03/15 01:37ID:???できるんだけど、その場合でも CGI プロセス自身からは見えないとまずいので、
そういうパーミッションのディレクトリにせざるを得ない。
で、suexec 使ってない apache だと、全ての CGI プロセスから丸見えってことだよね、
とかそういう話。
man CGI にも 「suexec にしる」 と書いてあるんだが、
mod_perl な人とかは suexec できないので辛いよな。
0436nobodyさん
04/03/15 02:14ID:???ファイルに書き込むときには使ったほうがいいんですかね?
いまいち必要かがわからないので誰か教えて…
0437nobodyさん
04/03/15 02:32ID:L0Oup+5/# SQLの発行
$sql = "select no, date, standard, exception, company, address, quality, class, url from $tblname where del = 0 order by no";
$result = $conn->exec($sql);
# 行数、フィールド数の取得
$rows = $result->ntuples;
$fields = $result->nfields;
# データファイルを作成
for($r = 0; $r < $rows; $r ++)
{
for($f = 0; $f < $fields; $f ++)
{
$v = $result->getvalue($r, $f);
$data .= qq|$v\t|;
}
chop($data);
$data .= qq|\n|;
}
print "Content-type:text/plain\n\n";
&jcode::convert(\$data, 'sjis');
print $data;
ここで、実際にIEでダウンロードすると、当たり前といえば当たり前ですが、ダウンロードファイル名がデフォルトでスクリプトのcgiファイル名となってしまいます。
一度、サーバーにファイル書き出しして開いて送ればいいのですけど、それをしないで好きなファイル名でダウンロードできるようにする方法ありますか?
perlというより、CGIですが。。
0438422
04/03/15 02:40ID:???お礼が遅くなってスマソです。教えていただいたリンク先ですが。。。
当方にはまだまだ敷居が高そうですが、今後の参考にさせていただきます。
>>436
未熟者が語るようなことではありませんが、例えば1つのファイルに複数の
書き込みがあったとしたらどうなると思います?
何らかの制御をして順番を決めないと競合してファイルが壊れてしまうはずです。
そのためにロックして1つの書き込みを処理している間は他の書き込みをロック
して防ぐことでファイルの破損を防ぐ。。。ということだと解釈していますが。
諸先輩方、いかがでしょうか?
0440nobodyさん
04/03/15 02:55ID:???ファイルロックは書き込み処理の寸前にするのでしょうか?
またflock($fp,LOCK_UN);といった感じでロックを開放する処理も書き込み後行った方がいいのでしょうか?
0441422
04/03/15 03:17ID:???ありがとうございます。
>>440
ファイルをopenする前にロック、closeしてから開放しないと
ロックする意味がないと思われますが?
http://www.google.com/search?q=%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB+%E3%83%AD%E3%83%83%E3%82%AF+%E3%81%A8%E3%81%AF&sourceid=opera&num=0&ie=utf-8&oe=utf-8
で
http://216.239.53.104/search?q=cache:JjxLPe-vA5IJ:tohoho.wakusei.ne.jp/wwwcgi8.htm+%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB+%E3%83%AD%E3%83%83%E3%82%AF+%E3%81%A8%E3%81%AF&hl=ja&ie=UTF-8
のような感じでしょうか。
0443nobodyさん
04/03/15 04:19ID:???>440-441
基本的には「ロック > 処理 > アンロック」、
例えば一つのファイルを更新する場合は「ロック > 読み > 書き > アンロック」
の順番が守られていれば、open() はロックの先でも後でも良い。
#ロックの方法論は別の話
現に、flock() は以下のようにして使う。
open(FILE, 'file.dat');
flock(FILE, 2); # ロックは open() の後
..
#読み書き等の処理
..
flock(FILE, 8); # アンロック
close FILE; # そして close()
ロックスレは途中荒れてるが読んでみると良い。
0444nobodyさん
04/03/15 04:23ID:???0445nobodyさん
04/03/15 04:39ID:???ブラウザ依存だけどこんな感じのを吐けばいい。IEなら動く
Content-Type: application/octed-stream
Content-disposition: attachment; filename=xxx
0447nobodyさん
04/03/15 09:46ID:???同じ時間になってしまうことはあるのでしょうか。
$key = time(); こんな感じで。
0448nobodyさん
04/03/15 09:56ID:???0450nobodyさん
04/03/15 11:59ID:???line 27のハッシュの使い方がまずいようなのですが、いまいちわからず何が悪いのかわかりません。
環境はWinXP + Active Perl 5.6 + An HTTPDです。
0451nobodyさん
04/03/15 12:01ID:???BEGIN {
use CGI::Carp qw(carpout fatalsToBrowser);
carpout(STDOUT);
}
# 画像ファイルのサイズ制限(KB)
$img_max = '100';
# 画像を保存するディレクトリー
$images = '画像を保存するディレクトリー';
use CGI;
$query = new CGI;
$filename = $query->param('File');
# ファイルを読み込む
while(read($filename, $buffer, 2048)) {
$file .= $buffer;
$file_size ++;
if($file_size > $img_max / 2) { &Error("ファイルサイズが大きすぎます"); }
}
0452nobodyさん
04/03/15 12:02ID:???$type = $query->uploadInfo($filename)->{'Content-Type'};
if ($type =~ /jpeg/i) { $ext = 'jpg' };
elsif ($type =~ /gif/i ) { $ext = 'gif' };
else { &Error("その形式の画像ファイルは保存できません"); }
$new_file = "test" . ".$ext";
# ファイルを指定ディレクトリにコピー
open(OUT, "> $images/$new_file");
binmode(OUT);
print(OUT $file);
close(OUT);
chmod(0666, "$images/$new_file");
# 完了メッセージの表示
print <<END_OF_HTML;
Content-type: text/html
<HTML>
<BODY>
ファイルのアップロードに成功しました。
</BODY>
</HTML>
END_OF_HTML
exit;
0453450
04/03/15 12:24ID:???このソ−スではファイルの入力部分のhtmlが不足していました。
書き足したところ上手くできました。お騒がせしました
0454nobodyさん
04/03/15 13:47ID:L0Oup+5/おおお。うまくいました。ありがとうございます!
0455nobodyさん
04/03/15 15:01ID:gPR3Vlyr@number=("1","3","7","16",,,);
のように、まったく規則性が無い数値が大量に入っている配列があるのですが、
この中から最大値および最小値を取り出す場合、何かいい方法は無いでしょうか?
■ このスレッドは過去ログ倉庫に格納されています