トップページ⇒php
1001コメント382KB

Perl コーディング初心者質問コーナー Part34

レス数が900を超えています。1000を超えると表示できなくなるよ。
0001前スレの連投で気分崩したので後よろ04/04/05 16:01ID:???
いらっしゃーい、Perlのコーディングで困ってる人のスレです。

【投稿する際の注意】
質問するときは内容をよく吟味してから投稿してください。
「コマンドの意味がわかんない」とかはマニュアル見ましょう。
回答者さんは何でも屋じゃありません。

1: 自分はこう言う事がしたい。
2: それでこんな風にやってみたが・・・
3: こんなエラーが出て上手く行かなかった。

最低でも1と3が無いと誰も答えられないよ。
ソース貼る時は、全角スペースでインデント忘れずに。
良い回答は良い質問から。一緒に勉強しましょう。

過去ログやお勧めサイトは >>2-10
0809nobodyさん04/05/16 02:01ID:???
Perl 5.6.1

物ぐさしないで新しいの入れてご覧。
ActivePerl build 631以前はTkが同梱されておりません。
0810nobodyさん04/05/16 05:37ID:???
これは具体例が無いと分からないね。
問題の起きるサンプルを書いて欲しいところ。
0811nobodyさん04/05/16 07:49ID:???
有る特定の日が何曜日か知る方法って有りますか?
今日、今だったらlocaltimeで取得出来ますけど。
引数で何とか出来そうですが分かりませんでした。
0812nobodyさん04/05/16 08:08ID:???
>>811
>>781
0813nobodyさん04/05/16 08:40ID:???
>>812
直ぐ前に有りましたか、失礼しました。
0814nobodyさん04/05/16 10:11ID:WJ6PDaM4
time値とプロセス番号をつかって、

10846903300057678
のように、表示させたいとしたいのですが、
(プロセス番号は、8桁未満のときは0を入れる)

$datafile = time . sprintf("%8d",$$);

だと、
108469033  57678
となってしまいます。
この空白を0で埋めるにはどうすればよいのでしょうか?
0815nobodyさん04/05/16 10:27ID:???
>>814
>>753
081681404/05/16 10:32ID:WJ6PDaM4
>>815
どうも。
$datafile = time . sprintf("%08d",$$) . ".csv";
で解決しました。
0817nobodyさん04/05/16 11:28ID:???
>>808
パッケージ名に全て小文字の名前を使うな。続きはそれを全部修正してから聞こう。
0818nobodyさん04/05/16 14:10ID:???
>>812
なぜ>>777を指さないでわざと>>781を指すんだろうね
0819nobodyさん04/05/16 15:59ID:???
CGI.pmを使ってPOSTする方法を教えてください。
0820nobodyさん04/05/16 16:26ID:???
>>819
ここでもマルチですか
0821nobodyさん04/05/16 16:53ID:???
他スレで回答もらってるのにここは放置か。
さすがマルチなだけあるな。
0822nobodyさん04/05/16 23:45ID:???
質問です。

ある日付の1日前の日付(YYYY/MM/DD)の取得は一度1970年よりの秒数に変換してから再びlocal関数に通すしかないのでしょうか?
もう一つ、
ある月に何日まであるかを返すには閏年の計算は必須でしょうか?(Perlに用意されていますか?)
0823nobodyさん04/05/16 23:50ID:???
ファイルをネットからDLする際に、更新されてたら全部読まずに追記の部分だけを読んで保存するにはどうしたらいいのですか?
たとえば2chのDATを読む時みたいに。
LPWのmirrorをみてみたのですが、更新されてるときは新しくDLするみたいでよくわかりません。
0824nobodyさん04/05/16 23:56ID:???
>>822
3/1の前日が2/28か2/29になる以外、すべての日の前日は固定ですが?
2月以外は何日まであるか固定ですが?
それは閏年によって変わるのだから計算は当然必要ですが?
perlにはそんなものを求める関数はありませんが?
0825nobodyさん04/05/16 23:59ID:???
>>822
Time::local
>>823
RFC 嫁。Range ほか
0826nobodyさん04/05/16 23:59ID:???
>>823
指定したバイト数以降を取得する。
0827nobodyさん04/05/17 00:04ID:???
>>825
>>826
即レスサンクスです。
調べてみますです
082882204/05/17 00:29ID:???
>>824 >>825
回答ありがとうございます。

Time::Localモジュールを使えば日付→経過秒数の変換が一発でできるようですね。
ある月の日数算出は普通に組み込んでみようと思います。

また困ったことがあれば質問しに来ます。
どうもありがとうございました。
0829nobodyさん04/05/17 06:58ID:???
>>822
use Date::Calc qw(Add_Delta_Days Days_in_Month);

my ($year, $month, $mday) = (2004, 3, 1);
($year, $month, $mday) = Add_Delta_Days($year, $month, $mday, -1);
print "date-1: $year, $month, $mday\n";

my $days = Days_in_Month($year, $month);
print "days: $days\n";
0830nobodyさん04/05/17 07:33ID:???
2の200乗の答えを標準出力に出力するプログラム作ってください!

083182204/05/17 08:22ID:???
>>829
それです!
わざわざサンプルソースまで書き出して頂きありがとうございます(´Д⊂ヽ

Days_in_Monthにあたる関数は自力で作れましたので、
Date::CalcのAdd_Delta_Daysだけを借りてみようと思います。

そして小一時間ほどppmと格闘しなんとかDate::Calcをインストールし、
5/1→4/30の移動を確認できました!
本当にありがとうございました。

# ついでにTime::Localもインストールしておきました。
0832nobodyさん04/05/17 10:01ID:???
>>830
宿題は自分でやろうな。な。
0833nobodyさん04/05/17 13:32ID:???
print "1606938044258990275541962092341162602522202993782792835301376\n";
0834nobodyさん04/05/17 13:44ID:???
perlのDBIでmysqlにデータを出し入れする時って、客の個人情報とかの場合でも平文でいいよね?
0835nobodyさん04/05/17 20:26ID:???
あ
083682304/05/18 02:17ID:???
>>825
>>826
探したのですが、rangeと検索してもほかの部分が見つかってしまってだめでした。
もうちょっとヒントをいただけませんか。
0837nobodyさん04/05/18 02:27ID:???
CPANをアンインストールすることはできますか?OSはWindowsXPです。
0838nobodyさん04/05/18 07:19ID:15Ww53+y
>>836
ttp://www.studyinghttp.net/rfc_ja/2616/sec14.html#sec14.35
0839nobodyさん04/05/18 07:21ID:???
>>830
use bignum;

>>834
ネットワーク(鯖)構成如何じゃない?
漏れても500円でなんとか(ry
084082304/05/18 08:16ID:???
>>838
ありがと〜。
がんばってみます
でもすごいむづかしいっぽい;;
0841nobodyさん04/05/18 12:03ID:???
>>834
Yahoo
0842nobodyさん04/05/18 22:40ID:???
誰かメールアドレスに使われる記号(@とか.とか)一覧が載ってるサイト知らない?

前に見つけたんだけど、URLがどっかいっちゃった;それでさっきから探してるけど、見つからないんだ。
0843nobodyさん04/05/18 22:43ID:???
RFCを見ろ。
0844名無しさん04/05/18 23:11ID:4Rd9YBtL
次のようなCGIの作成で質問です。
表の生成部分はなんとか出来そうなのですが
(a)ファイルの中から行を探して変更、削除する部分と
(b)追加する部分で同じ内容で複数行追加しないようにする部分
の方法が頭に浮かびません。どのような方法がありますか?サンプルソースを教えていただけないでしょうか?
1)予定テキストファイルを読み取り次のような表を生成します。
+−−−−+−+−+−+−+−+−+−+−+−・・・
|2004年06月|先月 |今月 |来月 |
+−−−−+−+−+−+−+−+−+−+−+−・・・
| 名前 |1|2|3|4|5|6|7|8|9・・・
+−−−−+−+−+−+−+−+−+−+−+−・・・
| 鈴木 | | |休| | |後| | |
+−−−−+−+−+−+−+−+−+−+−+−・・・
| 佐藤 | | | | |休| | | |
+−−−−+−+−+−+−+−+−+−+−+−・・・
| 田中 | | |前| | | |休| |
+−−−−+−+−+−+−+−+−+−+−+−・・・
2)先月、今月、来月の部分はリンクとなっていてCGIを呼び出し、先月の表、今月の表、来月の表を生成します。
3)名前もリンクになっていてフォームを呼び出し、SELECTタグにより年、月、日と、休、前、後を選択して予定テキストファイルに追加します。
4)休、前、後もリンクになっていて、フォームを呼び出し、予定テキストファイルから該当行を変更、削除します。
予定テキストファイルの内容は
名前ID<>年<>月<>日<>内容
n0001<>2004<>6<>3<>休
n0002<>2004<>6<>5<>休
n0001<>2004<>6<>6<>後
n0003<>2004<>6<>7<>休

名前と名前IDのリストファイルの内容
名前ID<>名前
n0001<>鈴木
n0002<>佐藤
n0003<>田中
0845nobodyさん04/05/18 23:28ID:???
業務丸投げですか?
まずは日本語からお勉強しようね。
お仕事をするには早すぎるようですよ。

ぶっちゃけ表はファイルから読み出すだけだし、
書き込みは重複を検査すれば良いだけだろ。
084684204/05/19 00:04ID:???
>>843
ありがとう!見つかったよ。

目的はメルアドのチェックじゃなくてsendmailに渡す際へんなスクリプトを排除したいだけなんだ。
で、なんか一杯記号は許可されてるみたいだから、結局「<」、「>」、「"」だけ切り捨てることにしたよ。

まだperl勉強足りないんだけど、perlって「$」、「@」、「%」とかを入力されても内部で途中で展開しないで
ただの文字列として扱われるみたいね。いい!
0847nobodyさん04/05/19 00:22ID:???
(a)ファイルの中から行を探して変更、削除する部分と
 Perlは不得手。全部読んで全部書き出すよろし。
 splice()を使うと幸せになれるかもしれない。

(b)追加する部分で同じ内容で複数行追加しないようにする部分
 重複チェックはハッシュを利用すると楽。
0848nobodyさん04/05/19 01:25ID:???
>>845
>まずは日本語からお勉強しようね。
>お仕事をするには早すぎるようですよ。

人のあらを見つけると大喜びで責め立てる。845はそういうむなしいやつ。
でもな、845だっていいところもあるんだよ。845のいいとこは↓が教えてくれる。
0849nobodyさん04/05/19 01:31ID:???
>>845のいいところ

>まずは日本語からお勉強しようね。
>お仕事をするには早すぎるようですよ。

人生にとって大切なことを的確にアドバイスしてあげたこと
0850nobodyさん04/05/19 02:31ID:???
PERLでの半角カタカナの扱いに困ってるよ・・・

例えば相手がフォームに「ササ」と半角カタカナで入力する。んで、漏れが
require "jcode.pl";
read(STDIN,$buffer);
$buffer =~ s/%([0-9a-fA-F][0-9a-fA-F])/pack("C",hex($1))/eg;
jcode::convert(\$buffer,"euc");
jcode::h2z_euc(\$buffer);
〜処理〜
jcode::convert(\$buffer,"sjis");
print $buffer;

ってやってもうまくいかない。相手がeucで送ってくれば大丈夫だけど他の文字コードだと駄目。
半角カタカナの文字列+全角文字列(例「ササ表示」)ならちゃんと全角カタカナへ変換できるけど。

なんかPERLメモとかには先にeucに変換してあればおkだなんて載ってるけど、全然おkじゃない・・・
相手がどんな文字コードで送ってきても華麗に半角カナを全角カナに変えれちゃうおっとこまえいませんか?
0851nobodyさん04/05/19 02:37ID:???
jcode::convert(\$buffer,"euc", 'z');
085285004/05/19 03:07ID:???
>>851
それも駄目なのさ。

多分問題は$bufferの中に半角カナしかないときなんだよね。他の文字も混ざってればちゃんと機能するんだけどね。
まあそんなにこだわることでもないけどできればなぁ
0853nobodyさん04/05/19 03:33ID:???
>>852
http://www.shtml.jp/mojibake/hankaku.html
0854nobodyさん04/05/19 03:33ID:???
ファイルの排他制御ってやっぱりいりますか?ちょっとしたCGIでtxtファイルから読みこんだり
するんですけでど、どれくらいのレベルから排他制御って必要になってくるんですか?
0855nobodyさん04/05/19 03:56ID:???
>>854
【Perl】ファイルロック(排他処理)について語ろう
http://pc5.2ch.net/test/read.cgi/php/1024795138/
085685404/05/19 03:56ID:???
すいません。読みこみだけのときは排他制御なんて必要ないんですよね?
でも、人が読みこんでる最中に誰かが新たにopenしようとしたらopenエラーになっちゃいますよね。

それは嫌なので一応flock等で誰かがファイルオープンしているときは待たせればいいんでしょうか?

open(DATA,"< test.txt");
flock(DATA,1);
なんたらかんたら
close(DATA);

みたいでよろしいですか?
085785404/05/19 03:59ID:???
>>855
すいません。専用スレがあるんですね。そっちで質問してみます。
0858nobodyさん04/05/19 05:48ID:???
>>850
他の文字と一緒に判別させるしかないよ。
"ササ"(Shift_JIS) = "算"(EUC-JP)だから。
0859nobodyさん04/05/19 06:29ID:Q40mcV4U
掲示板CGIで、+を半角スペースにデコードする処理があると思うんです。
あれをやってしまうと、本文に+が含まれている場合
空白になってしまうのですがどうすれば半角の+を表示することができるのでしょうか?

++
0860nobodyさん04/05/19 06:59ID:???
>本文に+が含まれている場合
「+」は「%2B」にエンコードされてるんだから無問題。
エンコードされていなかったら送信側のバグ。
0861nobodyさん04/05/19 07:00ID:???
エンコードから学習しよう
0862nobodyさん04/05/19 07:02ID:???
>>860に付け加えると、
デコードする際にまず+を半角スペースに変換して、それから%??を変換するのはこいつのため。
先に%2Bを+に変換してしまうと半角スペースになってしまう。
086385904/05/19 07:34ID:???

なるほど。コードをよくよく見てみたら、unpack(デコード)したあとに
+を半角スペースに置換する処理を行っていました。
どうもありがとうございました。
086485004/05/19 17:11ID:???
>>858
やっぱそうですかね、相手が送ってきたものを先にeucに変換する処理も相手が半角カナしか
入力しない場合、jcode.plではeucへの変換が正常におこなわれないみたいですね。

まあ、仕方ないということで半角カナは止めてね。って注意書きいれる事にしますた。
0865nobodyさん04/05/19 17:19ID:???
a.cgiに入力フォームがあって、b.cgiでそれを受け取るんですが、b.cgiでブラウザの
戻るボタンを押すと普通は
「セキュリティ保護のため、〜〜〜」
っていう文言がでてしまいますが、最近そうならないページを見つけました。
ttp://www.blueberryeye.co.jp/
の注文ページなんですが、間違っても簡単に前のページに戻れるのはいいなぁと思いますが、
やり方がわかるかたいますか?
0866nobodyさん04/05/19 18:01ID:???
lwpを使ったスクリプトからのアクセスを禁止する方法はありませんか
.htaccessでIP指定してdenyしてもだめだし
User-Agentがlibwww-perl/5.75なのでそれをdenyしても防げません。

lwpを使ったサンプル探して自分でいろいろテストしてみようと思いましたが
そういうのも見つかりませんし
何方かお知恵を拝借できませんでしょうか
086786604/05/19 18:02ID:???
×User-Agentがlibwww-perl/5.75なのでそれをdenyしても防げません。
●User-Agentがlibwww-perl/5.75なのでそれをdenyしてみましたが防げません。
0868nobodyさん04/05/19 18:04ID:???
>>865
前にもそんなネタ振った人がいたな。
入力値引き渡す方法はいろいろあるんだが
調べる気がさらさらない様子で放置されてたような。
086986504/05/19 18:12ID:???
>>868
入力値の引継ぎではなくて、多分キャッシュ関係なんだと思います。

例えば前ページに戻ったとき、フォームに入力していたのが消えずにそれぞれのボックス内に
残ってるんですよ。フォームのあるページを普通のHTMLで作った場合と同じ事が、CGIから吐き出されるHTMLでも
できてるって話です。

0870nobodyさん04/05/19 18:17ID:???
それをやる為には入力値の引継ぎ方法を考えないといけないわけなんだが。
0871nobodyさん04/05/19 18:20ID:???
>>865
スレ違い

>>866
板違い
0872nobodyさん04/05/19 19:01ID:???
キャッシュにフォーム値が残るとは初耳。
そんな方法があるのなら知りたいな。
087386504/05/19 19:03ID:???
>>870
そうなんですか?HTMLではその入力値の引継ぎを自動でやってるってことですか?

ただ単にCGIから吐かれたHTMLをブラウザに一定の時間のキャッシュを許すだけとかかなぁと
思ってました。

CGIで作られたページのキャッシュを制御するような機能をPERLで作れるのかなと。
0874nobodyさん04/05/19 19:19ID:???
POSTかGETかによってブラウザの挙動が違う
Perlのコーディングとは全く関係ない
0875nobodyさん04/05/19 19:23ID:???
>>873
ていうか>>865のページのソースでも読んでろって
087686504/05/19 19:41ID:???
>>875
何度も読んだ。

なんかみんな質問を勘違いしてるぽ

引継ぎなんてやっぱり関係ないみたい。ブラウザの戻るボタンで情報の再送信普通は自動
でしないけど、それを自動でやっている。っていう話でもない。

例えば、a.htmlにテキストボックスがある。そこに「あいうえお」といれてb.cgiに移る。
b.cgiが何するかなんてどうでもよくて、b.cgiからa.htmlに戻った場合、a.htmlのテキスト
ボックスには、さっき自分で書いた「あいうえお」が残ってるよね。

それは入力値の引継ぎなんて全く関係ない。ブラウザは新しく何かを読みこむわけじゃないし。

それのa.htmlがa.cgiになっても同じ様にするにはってことなんだけどね。
0877nobodyさん04/05/19 20:03ID:???
勘違いしてるのはお前の方だって。
さっさと消えろ。


では、次の人どうぞ。
087886504/05/19 20:13ID:???
>>877
う〜ん結局誰もわからないか。まあすぐに必要なわけでもないので、地道に色んなページで勉強してきます。
ありがとうございました。
0879nobodyさん04/05/19 20:30ID:???
香ばしい匂いが漂っていると思ったら、なるほど・・・
0880nobodyさん04/05/19 20:52ID:???
HTMLからCGIにSSIで値を渡すときってどうすればいいんでしょうか。
テキストカウンターなのですが、
 <!--#exec cgi="./counter.cgi?id=tes&md=4" -->
とするとSSIエラーが出ます。
?以降を外せば動くんですが・・・。
0881nobodyさん04/05/19 20:59ID:???
>>880
スレ違い
ttp://tohoho.wakusei.ne.jp/wwwssi.htm#Exec
0882nobodyさん04/05/19 21:07ID:???
少しでも気にくわない事があると、「消えろ!」とはねつけて殻に閉じこもってしまう大人になれない>>877。
しかし>>878よ、>>877は決して間違ってはいないんだぞ。そこの所は理解して欲しい。

>>877の本心を明かす男は↓
0883nobodyさん04/05/19 21:08ID:???
さっさと消えろ!
0884nobodyさん04/05/19 21:09ID:???
↑いいや違うぞ!本当の本心は↓
0885nobodyさん04/05/19 21:10ID:???
まんげが生えてきたーーー!!
0886nobodyさん04/05/19 21:11ID:???
>>865
POSTでアップロードしてから戻ると「セキュリティ保護のため、〜〜〜」
ってことならもう少し盛り上がったんだろうけどねぇ。

HTTPヘッダのLocationですっとばすぐらいしか策を思いつかないが、
Perlには関係ないか。
0887nobodyさん04/05/19 21:54ID:???
ちょっと不安になったんですが、
ある一つのデータファイルに対して、二つ以上の
Perlプログラムからファイルの読み書きを行う場合、
flockを使っていれば排他処理は問題ないですよね?
0888nobodyさん04/05/19 22:04ID:???
>>887
スレ違い
0889nobodyさん04/05/19 22:21ID:???
>>887
コード書いて試してからまたきてね。
0890nobodyさん04/05/19 22:33ID:ObBdfHPa
みなさんはじめまして。
以前、板違いのところで質問しまいましたが、親切にこちらを紹介して頂いたので
来た次第です。今回は教えを乞いたく伺いました。

私はsendmailを使ってメールフォームCGIを作ろうとしています。しかし、
No recipient addresses found in headerというエラーが出てしまいます。
エラーは受け取り人のアドレスがヘッダーにないといっているようなのですが、
変数の中にはアドレスがきちんと入っているんです。

現在、いろいろ試して最終的なソースはこうなっています。
$honbunていうのがbody部分(のつもり)です

$sendmail = '/usr/lib/sendmail -t';

if(open(SENDMAIL,"| $sendmail")){;
print SENDMAIL <<"EOM";
From: $motoadr_1
To: $mail_to
Subject: $staff_subj
Errors-To: $errmailadr
MIME-Version: 1.0
Content-Type: text/plain; charset="ISO-2022-JP"

$honbun
EOM
close(SENDMAIL);
}

ヘッダーとボディ部分の間は空行で区切ったのですが、これではダメなのでしょうか?お気付きの方はぜひとも教えてくださいませ。
0891nobodyさん04/05/19 22:57ID:???
>>890
\n\n
0892nobodyさん04/05/19 23:22ID:???
>>890
sendmailに食わしている内容が間違ってる可能性が高いと
思われるので、

open(SENDMAIL,"| $sendmail")

のところを

open(SENDMAIL,"> 適当なファイルのパス")

としてファイルに書き出してよく調べてみることをお勧め
する。

ありがちなのはヘッダ部に埋め込んでいる$ほげほげのどれ
かの末尾に改行がついていて、そこが空行になってしまって
いるって奴だね。
0893nobodyさん04/05/20 00:32ID:UfxuQY5M
#何回も正規表現を使うと
#$1,$2,$3に前回のマッチパターンが入っているからなのかうまく行かないことがあります

$s='921010';
my ($year,$month,$day)=($s=~m/^(\d+)(\d\d)(\d\d)$/);
print "$year,$month,$day\n";

$s2='hogemogesage';

($hoge,$moge,$sage) =($s2= ~m/(hoge)(moge)(sage)/);
print "$hoge,$moge,$sage";

->
92,10,10
4294967295,,Hit any key to close this window...
これを避ける簡単な方法ってないですか?
0894nobodyさん04/05/20 00:39ID:???
>>893
それ、単にコードの間違い。
0895nobodyさん04/05/20 00:45ID:???
>>893
↓のようにきちんと出力されたけど。
92,10,10 hoge,moge,sage
0896nobodyさん04/05/20 00:54ID:???
= ~
0897nobodyさん04/05/20 00:57ID:UfxuQY5M
あれ?何回かやってみたら下の方だけでもダメですた
ばかでした

結局
= ~→=~
お騒がせスマソ
0898nobodyさん04/05/20 02:58ID:746RqQ7w
ディレクトリ中から、内容に特定の文字列を含むファイルを一発でgrepってできますか?
ひとつづつopenしてgrepならできるんだけど。
0899nobodyさん04/05/20 03:14ID:???
そんなんやるべきじゃない。
0900nobodyさん04/05/20 04:43ID:???
>>899
もまいは生きてるべきじゃない
0901nobodyさん04/05/20 05:07ID:???
>>898
grep -nH 特定の文字列 `find ディレクトリ -type f`
# find ディレクトリ -type f | xargs grep -nH 特定の文字列
# find ディレクトリ -type f -exec grep -nH 特定の文字列 {} \;

0902nobodyさん04/05/20 05:55ID:???
>>880
apacheなら
http://httpd.apache.org/docs/howto/ssi.html#includingtheresultsofacgiprogram
0903nobodyさん04/05/20 09:10ID:???
>>876
Cookie使えばいいんじゃない?

090489804/05/20 19:49ID:???
>>901
レスありがと。でもperlだけではできないってことかな。
まじめにひとつづつopenするかー。
0905nobodyさん04/05/20 20:22ID:???
結局誰かが各ファイルを一つずつ open しなきゃならないことには変わりなく、
それを find にやらせるか、それとも perl が自分でやるか、というだけの違い
0906nobodyさん04/05/20 20:25ID:???
初心者ってより天然だな。
0907nobodyさん04/05/20 22:11ID:???
すみません。質問させてください。
perlでレスポンスヘッダに含まれるHTTPのバージョンを
変更したいのですが、できるのでしょうか?
0908nobodyさん04/05/20 22:40ID:???
>>907
出来なくは無い。
ひとつの方法を教えよう、perlでhttpサーバを書け。
レス数が900を超えています。1000を超えると表示できなくなるよ。