Perlコーディング初心者質問スレ Part 54
■ このスレッドは過去ログ倉庫に格納されています
0001nobodyさん
2007/02/10(土) 19:21:23ID:???【投稿する際の注意】
質問するときは内容をよく吟味してから投稿してください。
「コマンドの意味がわかんない」とかはマニュアル見ましょう。
回答者さんは何でも屋じゃありません。
1: 自分はこういう事がしたい。
2: それでこんな風にやってみたが・・・
3: こんなエラーが出て上手く行かなかった。
最低でも1と3が無いと誰も答えられないよ。
ソース貼る時は、全角スペースでインデント忘れずに。
良い回答は良い質問から。一緒に勉強しましょう。
お勧めサイトは >>2-10
前スレ http://pc10.2ch.net/test/read.cgi/php/1164519503/
過去ログ倉庫 ttp://user.ftth100.com/mirrorhenkan/perl/
0611nobodyさん
2007/04/14(土) 12:50:45ID:???http://pc11.2ch.net/test/read.cgi/tech/1173880452/10
utf8でスクリプト書くことがそんなに困るの?
今あるsjisやeucのスクリプトをエディタなどで変換するだけでしょ。
0612nobodyさん
2007/04/15(日) 03:41:41ID:???困るというか、モバイル機などでutf8がバケる機種があってそれに対する対策が自分はまだわかってないってだけです。
気分を害してしまったのならすみません。
0613nobodyさん
2007/04/15(日) 03:57:25ID:???0614nobodyさん
2007/04/15(日) 09:33:34ID:???古い機種つかってる人なんか無視
0615nobodyさん
2007/04/15(日) 11:29:23ID:???古い機種の携帯からのアクセス時だけJcode.pmか何かで
Shift_JISにエンコードすればいいだけの話じゃね?
if($ENV{HTTP_USER_AGENT} =~ /<適当に古い携帯の条件>/){
require Jcode;
$data = Jcode->new($data, 'utf8')->sjis;
print "Content-Type: text/html; charset=shift_jis\n\n";
print $data;
}else{
print "Content-Type: text/html; charset=utf-8\n\n";
print $data;
}
みたいに
0616nobodyさん
2007/04/15(日) 14:24:51ID:???611のリンク先をよく読んで。
utf-8を使うのは、あくまでもPerlスクリプトだけであって、
入出力はsjisだよ。
0618nobodyさん
2007/04/16(月) 08:23:29ID:???「Perlスクリプトはsjisで、内部で扱うデータは
utf8というのはできない」という事で、FAなのかな?
0619nobodyさん
2007/04/16(月) 11:00:24ID:???Windows上であっても。
0620nobodyさん
2007/04/16(月) 13:15:51ID:MjOOmdj6どのような方法がよいでしょうか?
指定方法は、
1.X行目からY行分
2.最終行(何行目かは分からない)から数えてX行目からY行分
の2通りです。
0621nobodyさん
2007/04/16(月) 14:24:24ID:???Perlで扱うマルチバイト文字は、内部的には「常に」utf8だよ。
use encoding を使えばsjis でスクリプトを書くこともできるが、
副作用があるから、よく理解した上で使わないといけない。
>>620
File::Tieを使うのが吉
0624nobodyさん
2007/04/16(月) 18:55:47ID:???}
このような条件式をもっとスマーティーに書きたいのですが・・・
良きアイデアをお願いします!
0625nobodyさん
2007/04/16(月) 19:12:41ID:???&foo;
}
0626nobodyさん
2007/04/16(月) 19:18:36ID:???なんか自分が情けなくなってきました・・
0630nobodyさん
2007/04/16(月) 22:29:15ID:???0631nobodyさん
2007/04/16(月) 22:35:41ID:???$x > -1 && $x < 1
は、個人的には直感的じゃないと思った。
こう書くんだとしても
-1 < $x && $x < 1
にしたほうが視覚的に分かりやすい。
0632nobodyさん
2007/04/16(月) 23:05:14ID:???とか書けたら一番幸せなんだけどな。
# ソースフィルタ使えばできるか?
0633nobodyさん
2007/04/16(月) 23:17:54ID:???0634nobodyさん
2007/04/16(月) 23:28:48ID:???0635nobodyさん
2007/04/16(月) 23:51:39ID:???他のサービスも同時に動いていて、Perlが使用してるメモリだけを知りたい。
0636nobodyさん
2007/04/17(火) 03:37:59ID:???0637nobodyさん
2007/04/17(火) 06:11:09ID:nSKTWe9a男性 $mensfile
女性 $ladysfile とメインのCGIで設定されていす。
チャレンジしてみたら、過去のログファイルが全て消えてしまい散々な目に会いました。下のどちらかでできそうな・・宜しくお願い致します。
(1)# 二重登録のチェックをします
if(-e $data){
open(FILE, "< $data"); # この時点でファイルは必ず存在します
while(<FILE>){
@v = split(/\t/);
if(@v[0] eq $name){
print "<center><b>すでに$nameさんは登録されています</b><br>\n";
print "「戻る」を押して入力しなおしてください</center>\n";
exit(0);
}
}
close(FILE);
}
0638637
2007/04/17(火) 06:12:56ID:nSKTWe9a&lock;
if(!open(IN,"$mail01"))
{print 'ファイルOPENができませんでした。',"\n"; exit;}
@dataline = <IN>;
close(IN);
unlink $lockfile;
foreach $DATA (@dataline) {
chomp $DATA;
if($DATA eq $MAIL){
print 'このメールアドレスは既に登録されています。',"\n";
exit;
}
宜しくお願い致します。
0639nobodyさん
2007/04/17(火) 09:23:10ID:???二重登録チェックの方法はひとまず置いといて、
ログファイルが消えちゃったってことは
書き込みの段階でしくじってるんじゃないの?
ありがちな例だと
× open (FILE, '> file.txt'); # 上書き(つまり消える)
○ open (FILE, '>> file.txt'); # 追加書き込み
とか。
0640nobodyさん
2007/04/17(火) 09:43:54ID:???ないし、ここで回答もらえるレベルに達してない質問の典型だね。
「日本語でOK」「エスパー回答者さんよろしく」ということで。
質問する側にも最低のスキルは必要で、問題を理解してもらえないことには
どうにもならんよ。
0642nobodyさん
2007/04/17(火) 10:35:21ID:???0644nobodyさん
2007/04/17(火) 17:05:48ID:???! int $x and ! int $y
って手もある罠、、、
0646nobodyさん
2007/04/17(火) 17:13:38ID:???0648nobodyさん
2007/04/17(火) 23:26:16ID:???何となくスレの雰囲気から察すると
『はじめてのPerl』マスターレベルは初心者じゃないよね、もう。
『続・はじめてのPerl』に至っては
題名だけ聞くと優しそうだけど、
マスターしたら、CPAN Authorくらいなれちゃうし。
俺的には、『はじめてのPerl』読みこなし中レベルだと解釈してるが、どうか?
0649nobodyさん
2007/04/18(水) 00:03:35ID:???じゃないかな
0650nobodyさん
2007/04/18(水) 00:12:31ID:???0651nobodyさん
2007/04/18(水) 08:05:12ID:???0652nobodyさん
2007/04/18(水) 10:28:13ID:???ファイルから読み込むことは可能でしょうか?
pack('C4', 255, 255, 255, 255) とすると4バイト(FF FF FF FF)になるかと思ったんですが、
8バイト(C3 BF C3 BF C3 BF C3 BF)になってしまいます・・・
0653652
2007/04/18(水) 11:33:42ID:???0654nobodyさん
2007/04/18(水) 11:56:14ID:???> 「Perlスクリプトはsjisで、内部で扱うデータは
> utf8というのはできない」という事で、FAなのかな?
リテラルの話であれば、Encode.pm で明示的に変換して使う分にはやりたい放題です。
Perl 5 の時点ではデフォルトで use bytes 状態なので、スクリプト内のリテラルが SJIS でも UTF-8 でも iso-8859-1 でも、perl にとってそれらは単なるオクテットシーケンスに過ぎません。
0655nobodyさん
2007/04/20(金) 14:39:02ID:???当たり前のようにmod_php前提のPHPに「Perl遅いし」とか言われても仕方ない。
0656nobodyさん
2007/04/20(金) 15:21:01ID:???0657nobodyさん
2007/04/20(金) 15:30:53ID:???> print "「戻る」を押して入力しなおしてください</center>\n";
にしてもきったねーHTMLだな
0658nobodyさん
2007/04/20(金) 15:59:34ID:???0659nobodyさん
2007/04/20(金) 17:22:02ID:???0660nobodyさん
2007/04/20(金) 22:18:03ID:???0661nobodyさん
2007/04/21(土) 05:09:19ID:???なにそれ?w
0662nobodyさん
2007/04/21(土) 09:34:59ID:???0663nobodyさん
2007/04/21(土) 13:00:06ID:???ロードできるようにするモジュールは無いか? という質問だとわかる。
0664nobodyさん
2007/04/21(土) 18:05:32ID:TzVmcQvU引数を省略すると$_が渡される
ようなサブルーチンを作る方法はある?
0665nobodyさん
2007/04/21(土) 18:17:53ID:???0667664
2007/04/21(土) 18:37:51ID:TzVmcQvUうわ、言われてみれば単純な話ですね…
ありがとうございました
0668nobodyさん
2007/04/23(月) 15:02:16ID:NvRgzOjiカウンターの箇所に「Location:…」も表示されてしまいます。
カウントした数字だけ表示して、指定したURLに遷移させる機能を保持するにはどうしたらいいですか?
何かトンチンカンなこと言ってたら指摘お願いします。
0669nobodyさん
2007/04/23(月) 16:33:16ID:LAYu+KhNホームページ作成ソフトがあったらいいのに・・・。
もし、プロ並みにキレイなホームページが作成が出来たとしたら、
情報商材で一旗あげようと思っているあなたの人生は変りますか?
【早くも成功者続出!】起業サイトビルダー
http://www.infotop.jp/click.php?aid=16484&iid=5683
0670nobodyさん
2007/04/23(月) 17:00:46ID:???どういうタイミングで遷移させたいのか。
表示したらすぐに遷移してしまったら、表示を見る暇がない。
クリックしたら、であれば、出力したカウント文字列なりイメージにaタグを張ればよいです。
0671nobodyさん
2007/04/23(月) 18:06:45ID:???すいません説明不足でした。
今作っているのは、
メールフォームに入力して送信ボタンを押すと、
送信完了ページにアクセスカウンタが表示されるというもので、
SSIを使ってそのページにカウントを表示させています。
0673nobodyさん
2007/04/24(火) 14:35:35ID:???送信完了ページにSSIのカウンタを表示させているのはわかったが、なぜカウントの出力と一緒に
Locationヘッダを出力しようと思ったのか、それを書いてくださいよ。
0674nobodyさん
2007/04/25(水) 03:14:10ID:???Location(も使い方間違ってるがw)じゃなく、
入力したフォームの値を隠し属性にして
同時にカウンタも仕込んだ別のページを表示させる。
0675nobodyさん
2007/04/25(水) 04:08:26ID:???・静的HTMLで作られた送信完了ページの冒頭に<meta>でrefreshでも入れとく。
・動的に吐かれる送信完了ページを吐く前の段階でカウント*だけ*して(表示要らない)
送信完了ページを吐く代わりに Location: を吐いて希望のページに飛ばす。
期待してる動作はこんな感じなんじゃないのかな。
0676nobodyさん
2007/04/25(水) 16:31:04ID:???送信完了ページはCGIが吐き出すタイプだね?
その中にSSIのカウンタを仕込もうとしてprint "Location:カウンターのスクリプト"とか書いたんじゃないの?
メールフォームのスクリプトにカウンターの機能を組み込んで送信完了ページに書き出せばいいじゃん。
SSIなんて必要ないよ。
0677nobodyさん
2007/04/25(水) 18:21:45ID:???やりたいことはフォームに入力されたデータをCGIで受け取り一括編集です。
<tr><td>NO</td><td>項目1</td><td>項目2</td></tr>
<tr><td><input type="hidden" name="no" value="1_g9gnt3">1_g9gnt3</td>
<td><input type="text" name="text1"></td><td><input type="text" name="text2"></td></tr>
<tr><td><input type="hidden" name="no" value="2_ghtt3d">2_ghtt3d</td>
<td><input type="text" name="text1"></td><td><input type="text" name="text2"></td></tr>
・
・
とログのデータと比例して続くフォームからデータを受け取り、
ログ形式 log.txt
------------------------
1_g9gnt3<>text1<>text2<>
2_ghtt3d<>text1<>text2<>
・
・
------------------------
と続くログとを照らし合わせてPOSTデータの「no」とログの先頭が一致する場合、
一致した行のtext1とtext2を書き換えたいと思っています。
一行ずる編集するスクリプトは書けましたが、
POSTで受け取った指定行を一括で同時編集するソースがわかりません。
お手数おかけしますが是非ご教授ください。
0678nobodyさん
2007/04/25(水) 20:05:49ID:???0679nobodyさん
2007/04/25(水) 23:47:47ID:???たとえば、下記のようなデータが投げられたときのソースを教えていただければと思います。
mode=edit&no=1_g9gnt3&text1=hoge1&text2=huga1&no=2_ghtt3d&text1=hoge2&text2=huga2
こんな感じのデータが投げられたときどうやったらやりたいことができるのか、
全く持ってわかりません。。
0680678
2007/04/26(木) 00:06:04ID:???分解できないのか? 変数に格納できないのか? ループが分からないのか? 顔が濡れて力が出ないのか?
0681nobodyさん
2007/04/26(木) 00:12:28ID:???さらにはスレ違いの予感さえする。
でもヒマなので、親切にしてやる。
(1) &で分割してから配列に格納。
(2) ループで配列内を、=で分割してからハッシュに格納。
あとは…分かるな。
普通は、CGI.pm使うのが一般的だろうな。
0682nobodyさん
2007/04/26(木) 00:42:18ID:???>>681
わざわざご親切にありがとうございます。
流れとしては
[&]で分割後配列へ格納→配列分ループ→ループ中に[=]で分割→noと一致する行があれば書き換え
という感じかと思い、色々ソースを書いてみましたが無限ループにはなるは、
配列分のループが上手く行かないとかぐっちゃになってしまって。。
(それで具体的なソースが欲しくなり、教えて君になってしまいました。。すみません。。)
ちょっと外出先にソース忘れてきちゃったので明日もう一度やってみます。
ハッシュとCGI.pmについて教えていただいたので調べてみます。
ありがとうございます。
0684682
2007/04/26(木) 10:14:48ID:???アドバイス、、よろしくお願いいたします。。
$formdata="mode=edit&no=1_g9gnt3&text1=hoge1"
. "&text2=huga1&no=2_ghtt3d&text1=hoge2&text2=huga2";
@pai = split(/&n/,$formdata);
open(IN,"$logfile") || print "error\n";
while($date = <IN>) {
$date =~ s/\x0D\x0A|\x0D|\x0A//;
my($no, $text1, $text2) = split(/<>/, $date);
for ($i=0;$i<@pai;$i++){
push @line, split(/&/,$pai[$i]);
($names, $values) = split(/=/,$line[$i]);
$p{$names} = $values;
if($no == $p{o}){
#書き込み処理
}
}
}
close(IN);
0685nobodyさん
2007/04/26(木) 10:50:46ID:???書いたとおりに動いてるだろと言われて終了だよ。
あとはエスパーさんよろしく。
なぜ/&n/でsplitするのかとか、あとでまたsplitするのはなぜかとか
$text1, $text2はどこへいったのかとか、@lineどんどん太るぞとか
いろいろつっこみどころはありそうだが。
0686682=677
2007/04/26(木) 10:59:54ID:???レスありがとうございます。
$logfile は下記です。
log.txt
------------------------
1_g9gnt3<>text1<>text2<>
2_ghtt3d<>text1<>text2<>
・
・
------------------------
やりたいことはログの一括編集です。
(掲示板なんかの編集機能などログファイルの一行だと思いますが
それの複数行を一括で編集するような機能)
&nの理由は&だけで分割したらforループ時回数がわからなくなってしまうなぁ、、
というなんとなくでやってみました。ループ中にもう一回splitした理由は
=で分割しないといけないかなぁ、、という理由です。
@lineが太るということについてはわかりません、、すみません。。
0687nobodyさん
2007/04/26(木) 12:23:48ID:???あまりにアレすぎて添削する気が萎えるので、チェックポイント。
・フォームデータのデコードはCGI..pmにやらせる
・フォームでtext1とtext2が何回も出てくるので、それが各行のnoの値とちゃんと対応させられるか保証がない
→そういうときは、
<tr><td><input type="hidden" name="no" value="1_g9gnt3">1_g9gnt3</td>
<td><input type="text" name="text1_1_g9gnt3"></td><td><input type="text" name="text2_1_g9gnt3"></td></tr>
というように、name属性にnoの値をつけて、CGIプログラムでデータを受けたときに参照しやすいようにすると吉。
つづく
0688nobodyさん
2007/04/26(木) 12:27:08ID:???use CGI;
use strict;
my $q = new CGI;
# noに指定された値の入力欄が存在するかの判定用
# name="no"のhiddenタグと、対応するtext1、text2のフィールドが
# 必ず対応していることが条件
my %no_exist = map { $_ => 1 } $q->param("no");
my @data;
open(R, $logfile) or die $!;
while (<R>) {
my($no, $text1, $text2) = split(/<>/);
push(@data, $no_exist{$no}
? join("<>", $no, $q->param("text1_$no"), $q->param("text2_$no"))."<>\n"
: $_
)
}
close(R);
open(W, "> $logfile") or die $!;
print W @data;
close(W);
※全角スペース使用のためコピペ注意。
結局全部書いてしまった…orz
動作確認してません。
$logfileの中身を@dataに全部食わせるので、ファイルサイズがでかいとメモリも食います。
0689nobodyさん
2007/04/26(木) 13:30:23ID:???「input nameの付け方が悪い」
これだけでおk
0690nobodyさん
2007/04/26(木) 14:21:39ID:2xFOBqUQそのディレクトリに別のディレクトリの中身をコピーしするCGIを作りたかったのですが
動きません>< 環境はジオシティーズのジオプラスです
ソース
#!/usr/bin/perl
# 1.REQUEST_METHODをチェックしてリクエストプロトコル(GET or POST)を判断する
if( $ENV{'REQUEST_METHOD'} eq "GET" ) {
# 2.GETであれば、QUERY_STRINGからクエリを読み込む
$buffer = $ENV{'QUERY_STRING'};
} else {
# 3.POSTであれば、CONTENT_LENGTHを使用してリクエストのサイズを調べ、
# 標準入力からクエリを読み込む
read( STDIN, $buffer, $ENV{'CONTENT_LENGTH'} );
}
print "Content-Type: text/html", "\n\n";
print "<HEAD>", "\n";
print "<META HTTP-EQUIV='Refresh' CONTENT='5;URL=index.html'>", "\n";
print "<META name='GENERATOR' content='IBM HomePage Builder 2001 V5.0.3 for Windows'>", "\n";
print "<title>作成</title>", "\n";
print "</HEAD>", "\n";
print "<font size=5>書き込み中</font>", "<br>\n";
print "<b>Data</b> ", $buffer, "<br>\n";
print "<b>Split Data</b><br> ", "\n";
0691nobodyさん
2007/04/26(木) 14:25:00ID:???本を一冊読め・・・
ソースにはディレクトリなんてひとかけらも出てきてないだろ
クエリ受け取ってそれ表示してるだけ。
もうなんていうか死ねばいいのに。
0692690
2007/04/26(木) 14:25:54ID:2xFOBqUQmy @pairs = split(/&/,$buffer);
foreach $pair (@pairs){
# 5.イコール( = )で連結されたキーと値を分割(kye=value)
my($name, $value) = split(/=/, $pair);
# 6.プラス( + )をスペース( )に変換
$value =~ tr/+/ /;
# 7.16進数にエンコードされた文字列をデコード
$value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
@data = ($name, $value);
print "$name : $value<br>";
mkdir (".$name", 0755) || die "ディレクトリ生成失敗 : $!";
open(IN,"./index.html"); #コピー元ファイル をオープン
while(<IN>){ # 一行毎の読み込みループで変数$Bufに読み込む
$Buf .= $_;}
close(IN); #ハンドル IN が不要になったので閉じる
open(OUT,"> ../$name/index.html); #コピー先ファイル をオープン
print OUT $Buf; #ソースの内容($Buf)を書き出す
close(OUT); #ハンドル OUT が不要になったのでクロス
}
と、このように書いてみましたがエラー表示が出て動きません><
エラーの詳細がわからないので直し方がわかりません。
エロイ人教えてください。
0693nobodyさん
2007/04/26(木) 14:28:28ID:???0694nobodyさん
2007/04/26(木) 14:30:01ID:???http://mixi.jp/view_bbs.pl?id=17607679&comm_id=1401396
Perlに関すること、cgiに関すること
なんでも質問できるコーナーです(たとえばApacheとかでもOKとします!)
(Web系であればOK)
ルール:
Google検索で調べてわかるようなことでも質問してもOKです
(初心者のうちは、どの情報を取捨選択したらイイのかわからないと思うので)
回答してくださるかたは、暖かく質問者を迎えてやってください
o(^^o) (o^^)o
ここ池
0695nobodyさん
2007/04/26(木) 14:30:49ID:???スクリプトの2行目に
use CGI::Carp qw(fatalsToBrowser);
と書きましょう。
シンタックスエラーの原因が表示されるようになります。
# まずは、これでいいんじゃね?>ALL回答者
0696682=677
2007/04/26(木) 17:01:44ID:???ずっとあれからやってたのですがなぜかハッシュに代入されなくて
ソース部分を別CGIとして作り、データを投げたところ上手く行きました。
これからもっともっと勉強して色々覚えたいと思います。
本当にありがとうございました!
0697nobodyさん
2007/04/26(木) 23:13:22ID:???動かすにはどうしたらいいのでしょうか?
IO::SelectはIO::Socketでないと使えないのでしょうか?
0698nobodyさん
2007/04/27(金) 09:34:20ID:???素直にsocket使うべき。
0699nobodyさん
2007/04/27(金) 14:53:44ID:???0700nobodyさん
2007/04/27(金) 20:33:48ID:???入所前(7年前)にはそんなの無かったはず
いやぁ〜プログラミングは楽しいね
0701nobodyさん
2007/04/27(金) 21:57:47ID:???0702nobodyさん
2007/04/27(金) 22:44:25ID:???0703nobodyさん
2007/04/28(土) 00:13:57ID:???下のように書いても5秒どころか30秒位待たされることがあるよ。
なんでだろう?
$ua = LWP::UserAgent->new;
$ua->timeout(5);
0704nobodyさん
2007/04/28(土) 01:22:35ID:???Get/set the timeout value in seconds. The default timeout() value is 180 seconds, i.e. 3 minutes.
The requests is aborted if no activity on the connection to the server is observed for timeout seconds. This means that the time it takes for the complete transaction and the request() method to actually return might be longer.
0705nobodyさん
2007/05/02(水) 11:13:15ID:sZgTnz1Hmy $a = 2/3;
としたら一体どうなるのでしょうか?
割り切れない数なのでforの∞ループみたいに悲惨なことになりますか?
今暗算練習のCGIを作ってます。足し算引き算までつけてあるのですが、
割り算もつけようかなと考えてたらこの問題にぶちあたりました。
my $a = int (rand 100) / int (rand 100);
実際はこんな感じで使おうと思ってたのですが、割り切れない計算になったときどうなるのでしょうか?
適当なところでやめてもらえるのでしょうか?
それとも/演算子に対して「小数点第5位まででやめろ」という命令をあらかじめだしておけるでしょうか?
0706nobodyさん
2007/05/02(水) 11:14:07ID:???0707nobodyさん
2007/05/02(水) 11:19:00ID:???やらずに質問するの?
脳の一部に障害のある方ですか?
0708nobodyさん
2007/05/02(水) 11:28:03ID:???これが気になってんだろう
0709nobodyさん
2007/05/02(水) 11:35:47ID:???> my $a = int (rand 100) / int (rand 100);
これ、計算せずにエラー吐いてくれるときがあるよ。
0710705
2007/05/02(水) 11:58:22ID:sZgTnz1Hその通りです。
>ときがあるよ。
というのは運任せという意味ですか?
それともuse strictのような無限ループコードストップモジュールでもあるという意味ですか?
■ このスレッドは過去ログ倉庫に格納されています