こんばんは、皆さん。
以下のプログラムは1回しか__DATA__を読み込まないですが、
2回めのprintで__DATA__を表示させるにはどうしたらよいのでしょうか?
------------------------------------------------------
#!/usr/bin/perl
$str = "DATA";
$aaa = &test($str);
print $aaa;
sub test($){
$instr = @_[0];
foreach (<$instr>){
print;
}
foreach (<$instr>){
print;
}
}
__DATA__
1
2
3
------------------------------------------------------
No.2ベストアンサー
- 回答日時:
DATA は seekable なファイルハンドルなので、tell と seek を使って読み込み位置を変更することができます。
最初のループの前に
$fpos_top_of_instr = tell $instr;
を入れ、次のループの前に
seek $instr, $fpos_top_of_instr, 0;
を入れてみて下さい。
# seek $instr, 0, 0; と強制的に先頭に戻すと・・・
この回答への補足
お返事ありがとうございます。
詳細が知りたいのですが、その情報はどこに
掲載されていますでしょうか?
Webでは見つかりませんでした。
よろしくお願いします。
No.5
- 回答日時:
> なんで@instrs=<$instr>;でforeach(@instrs)にするとうまく動くんですか?
print していただくとわかりますが、 @instrs は (1,2,3) になっていて、foreach(@instrs) の中の print; でそれぞれの要素が表示されます。
コード2は tell の文がコメントアウトされているので、$fpos_top_of_instr が定義されておらず、return の上の seek $instr, $fpos_top_of_instr,0;が seek $instr, 0,0; と同義になっています。それで return <$instr>; しているのでコード全体が戻り値になって @aaa の内容として表示されたのでしょう。
一応、私が意図したところのコードを添付しておきますね。
#!/usr/bin/perl
$str = "DATA";
@aaa = &test($str);
print "aaa= @aaa\n";
sub test($){
$instr = @_[0];
$fpos_top_of_instr = tell $instr;
foreach (<$instr>){
print "data1= $_";
}
seek $instr, $fpos_top_of_instr, 0;
foreach (<$instr>){
print "data2= $_";
}
seek $instr, $fpos_top_of_instr, 0;
return <$instr>;
}
__DATA__
1
2
3
No.4
- 回答日時:
>指定しないと最後に評価した値が返却されたような。
おっしゃられるとおりで、「&test は何も返してない」は間違いだったと思います。すみません。&test で最後に評価されているのは print 文で1が返りそうな気がしますが $aaa は空みたいですね~。↓
>でも1回は表示されました。なぜでしょうかねぇ。
表示されたのはきっと1回目の foreach の中の print の結果ですね。6行目の print $aaa; を print "aaa= $aaa\n"; とすると、そこでは何も表示されていないことが分かります。
2つ目の foreach の下に
seek $instr, $fpos_top_of_instr, 0;
return <$instr>;
を追加して、5-6行目を
@aaa = &test($str);
print "aaa= '@aaa'\n";
とすると aaa= '1 2 3' と表示されました。
本題とは関係ないことで失礼しました。
この回答への補足
お返事ありがとうございます。
ちょっとなんか変ですよ。
これって関数ですか?サブルーチンですか?
なんで@instrs=<$instr>;でforeach(@instrs)にすると
うまく動くんですか?
理屈がわかりません。
すいません、お礼にしか書けなくなってしまったので、こちらに書きます。
seekをどこに入れたらいいのかわからなかったので、
コード1のようにすると、結果1になりました。
コード2だとaaa=''の「'」の中に、ソースコード全体が入りました。
なぜでしょうか?
---コード1-----------------------------------
#!/usr/bin/perl
$str = "DATA";
@aaa = &test($str);
print "aaa='@aaa'\n";
sub test($){
$instr = @_[0];
#$fpos_top_of_instr = tell $instr;
foreach (<$instr>){
print;
}
#seek $instr, $fpos_top_of_instr, 0;
#seek $instr, 0, 0;
foreach (<$instr>){
seek $instr, $fpos_top_of_instr,0;
return <$instr>;
print;
}
}
__DATA__
1
2
3
---結果1-----------------------------------
1
2
3
aaa=''
---コード2-----------------------------------
#!/usr/bin/perl
$str = "DATA";
@aaa = &test($str);
print "aaa='@aaa'\n";
sub test($){
$instr = @_[0];
#$fpos_top_of_instr = tell $instr;
foreach (<$instr>){
print;
}
#seek $instr, $fpos_top_of_instr, 0;
#seek $instr, 0, 0;
foreach (<$instr>){
print;
}
seek $instr, $fpos_top_of_instr,0;
return <$instr>;
}
__DATA__
1
2
3
No.3
- 回答日時:
> 詳細が知りたいのですが、その情報はどこに
> 掲載されていますでしょうか?
tell と seek でファイルの読み込み位置を制御するというのはファイル操作の基礎知識みたいなものなので、どこにでも載っていると思います。
ただ、DATA を再読み込みすることを念頭に探すと、そもそもそんなことをする人はあまりいないでしょうから、途端に見つけるのが難しくなります。
DATA はファイルハンドルですから、seek さえ知っていれば「DATA を seek できないか?」程度のことはすぐに思い付いたでしょうし、ちょっと試してみれば tell が必要なこともすぐに気付いたでしょう。
ファイル操作に限らず、どんな機能の関数があるのか一通り知っておかれるとよいと思いますよ。
貴重な情報をありがとうございます。
tellもseekも知りませんでした。
ということは基礎がまだ身についていないということですね。
初心者の領域を脱してないのは実感していますけど。
DATAを再読み込みするのは一般的じゃないんですね。
確かにデータをソースのファイルに入れるのは、ちょっと考え方が変ですね。
こういう場合は__DATA__を使ってデータを入れるのが良い、という例があるといいんですが。
No.1
- 回答日時:
# これじゃだめでしょうか・・
# ちなみに、&test は何も返してないので $aaa は空ですよ。
#!/usr/bin/perl
$str = "DATA";
$aaa = &test($str);
print $aaa;
sub test($){
$instr = @_[0];
@instrs=<$instr>;
foreach (@instrs){
print;
}
foreach (@instrs){
print;
}
}
__DATA__
1
2
3
この回答への補足
そうなんですか?
これで動かしたら動きましたけど。
returnで明示的に戻り値を指定しないといけないんでしたっけ?
指定しないと最後に評価した値が返却されたような。
それでも、表示されないはずですね。
でも1回は表示されました。
なぜでしょうかねぇ。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- その他(プログラミング・Web制作) pythonでDBのカラム名で取得したオブジェクトの値を表示したい 1 2022/05/13 03:41
- Excel(エクセル) PHPプログラムをエクセルに張り付けると検索ボックスがでてくる! 3 2022/05/08 07:10
- その他(プログラミング・Web制作) Python - Excel で Webからデータを連続取得したいのですが エラーが出ます 1 2023/07/06 20:08
- PHP PHPでCookieを使った訪問回数について 1 2023/05/28 14:10
- CGI htmlからパラメータで、cgiに渡したい。 1 2023/02/06 16:15
- その他(プログラミング・Web制作) python 2 2022/12/23 09:06
- PHP if(preg_match("/[^0-9]/",$gu_d)){意味を教えてください。 1 2022/05/06 05:37
- その他(プログラミング・Web制作) VScodeでpythonプログラムの関数を実行したい 2 2022/07/13 19:24
- C言語・C++・C# C#テキストボックスの文字を配列にいれてその後表示する 4 2022/07/17 04:47
- その他(プログラミング・Web制作) pythonのmap、結果の利用は1度だけ? 5 2022/06/11 12:33
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
int(input("○○"))の使い方
-
16進の10進変換について
-
I2C接続のLCDディスプレイを使う
-
c言語 16進数の2進数への変換
-
pythonで演算子を変数に代入す...
-
【至急!!!】python言語で本を見...
-
シェルスクリプトで、空白(ス...
-
関数「exists」と「defined」の...
-
awkの正規表現での最左最短マッ...
-
pythonの*
-
pythonのmap、結果の利用は1度...
-
pythonを使ったプログラミング...
-
Pythonでターミナルに文字を出...
-
[Ruby] irbにおける文字化け
-
Application.ScreenUpdating = ...
-
formで特定のinputを送信しない...
-
文字の横にプルダウンを表示さ...
-
JSONで文字列が長い時
-
どちのほうがすきですか?
-
実行時エラー 3020の対策
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
Pythonでターミナルに文字を出...
-
16進の10進変換について
-
パイソンのクラスについて
-
【至急!!!】python言語で本を見...
-
シェルスクリプトで、空白(ス...
-
I2C接続のLCDディスプレイを使う
-
int(input("○○"))の使い方
-
数値かどうかの判定方法
-
pythonで演算子を変数に代入す...
-
awkの正規表現での最左最短マッ...
-
Pythonでコンソールをクリアす...
-
pythonを使ったプログラミング...
-
c言語 16進数の2進数への変換
-
関数「exists」と「defined」の...
-
ソケットでのデータ送受信につ...
-
pythonの*
-
Perlの例文でif($a==1&&$b==5&&...
-
数値をスラッシュで区切る方法
-
変数の中は文字列か数値か調べ...
-
PythonでUTF8の文字列をリスト...
おすすめ情報