• ベストアンサー

while文がうまく動かない

a.txt a b c b.txt x y z として次のプログラムを実行 open(A,"<a.txt"); open(B,"<b.txt"); while($a=<A>){ while($b=<B>){ print "$a>>>$b<br>"; } } close(A); close(B); すると実行結果が以下のようになりました。 a>>>x a>>>y a>>>z 上の結果だけではなくてa.txtがbの時cの時も出力されるつもりで書いたのですがなぜかaの時しか出力されません。どなたか理由が分る方いませんか? ちなみに Linux FedoraCore2 perl5 を使用しています。

  • Perl
  • 回答数3
  • ありがとう数3

質問者が選んだベストアンサー

  • ベストアンサー
  • masaboo
  • ベストアンサー率58% (7/12)
回答No.2

open(A,"<a.txt"); while($a=<A>){   open(B,"<b.txt");   while($b=<B>){     print "$a>>>$b<br>";   }   close(B); } close(A); なのでは?

--KING--
質問者

お礼

できました。ありがとうございました。

その他の回答 (2)

  • hara_peko
  • ベストアンサー率28% (11/38)
回答No.3

open(B,"<b.txt"); を最初のwhileループの内側に移動してください。 open(A,"<a.txt"); while($a=<A>){ open(B,"<b.txt"); while($b=<B>){ print "$a>>>$b<br>"; } } 今回のとは関係有りませんが、変数$a,$bはsortの時に使われる変数なので、通常スクリプトを書く時に使うとuse strictしていてもミスに気づきづらくなります。できればさけた方が無難でしょう。

--KING--
質問者

お礼

できました。ありがとうございました。

  • ttyp03
  • ベストアンサー率28% (277/960)
回答No.1

原因は B が A の1回目のループでEOFまで達してしまうからです。 A の2回目のループで B から取得しようとしても EOF なので何も取得できず終了しています。 対処としては B のループが終わったあとにファイルポインタを先頭に戻す必要があります。 open(A,"<a.txt"); open(B,"<b.txt"); while($a=<A>){  while($b=<B>){   print "$a>>>$b<br>";  }  seek(B,0,0); } close(A); close(B);

--KING--
質問者

お礼

ご回答ありがとうございました。

関連するQ&A

  • whileの$_とforeachの$_の関係

    以下のコードにおけるwhileとforeachでの$_の使いかたについて教えてください。 my @foos = qw( a b ); sub foo1 {   open FH, "foo.txt";   while (<FH>) {     chomp;     print "$_";   } #  while (my $x = <FH>) { #    chomp $x; #    print "$x"; #  }      print "\n"; } sub foo2 {   foreach (@foos) {     print "<$_>";     foo1();   }   print "\n"; } foo2(); foo2(); このコードと同じディレクトリに以下のような内容のfoo.txtをおいて実行します。 x y すると、以下のような結果が得られました。 <a>xy <b>xy <>xy <>xy 一回目のfoo2で@foosの内容が消えてしまいます。一方、コメントアウトしてあるようにwhileに変数($x)を使うと期待したとおりの結果が出ます。なぜ、このような結果になるのでしょうか。ご存知の方がいらっしゃったら教えてください。宜しくお願いします。ちなみに、WinXP + ActivePerl(v5.8.6)で試しました。

    • ベストアンサー
    • Perl
  • ファイル読み込みマッチングについて

    現在二つのファイルをつき合わせて一致しない ファイルを出力するようなものを作っています。 例ですが。 ---a.txtココカラ--- aaa bbb ccc ---ココマデ--- ---b.txtココカラ--- aaa ccc ddd fff ---ココマデ--- 上記ファイルを照らし合わせて 以下のファイルを出力 ---c.txtココカラ--- bbb ---ココマデ--- のように出力させたいのですが。 自分の作成したものは ---a.plココカラ--- open(IN1,"a.txt") || die $!; open(IN2,"b.txt") || die $!; open(OUT,">c.txt") || die $!; sub hikaku { while(<IN2>){ if($a eq $b){ return; } } print OUT "$a"; return; } while(<IN1>){ $a = $_; &hikaku; } close(IN1); close(IN2); close(OUT); ---ココマデ--- いろいろテストをしてわかったことですが サブルーチンの while(<IN2>) そのままに なる一回しか回らないことがわかりました。 これは偽になった後、サブルーチンを抜けまた 回ってきた時に偽と判断されるからでしょうか? プログミング自体始めたばかりなので、こんなん あかんに決まってるやん!とか一からだなこれ!! とか導いていただけるなら厳しいご指摘お待ちして おります。 長くなりましたがよろしくお願い致します!!

    • ベストアンサー
    • Perl
  • foreach構文をwhile構文で実現したい。

    下記にありますforeach構文をwhile構文で実現しようと試みているのですが 何故か同じように実現できず、無限ループになっているような気がします。 どこに問題があるのか当方ではわからない為、どなたかご教授いただけませんでしょうか。 ------------------------------ $ cat list1.txt 01<>ああああ 01_01<>あAAA 01_02<>あBBB 01_03<>あCCC 01_04<>あDDD 02<>いいいい 02_01<>いAAA 02_02<>いBBB 02_03<>いCCC 02_04<>いDDD ------------------------------ ■成功版 open(IN, "<list1.txt"); @datas = <IN>; close(IN); open(OUT, ">date.txt"); foreach (@datas) { chomp; ($a, $b) = split(/<>/, $_);#$_は省略できます。 print OUT "'$a'=>'$b',\n"; } close(OUT); ■取組版 open(IN, "<list1.txt"); @datas2 = <IN>; close(IN); open(OUT, ">date2.txt"); while (@datas2) { s/^/'/; s/<>/'=>'/; s/$/',/; print OUT; } close(OUT);

    • ベストアンサー
    • Perl
  • shellの文法 deffとdo while ??

    最終目標はaaa.c(aaa.txtの中身)とaaa_x.c(bbb.txt)、bbb.cとbbb_x.cのdiffをとり、差分をtxtファイルに出力したいと思っています。 ファイル名の規則は1パターンのみで、_xの前の部分が同じもの通しがdiffをとる対象になります。 (パスはすべてばらばらです) aaa.txtの中身 ファイルパス/ファイル名 a/b/c/aaa.c aa/bb/cc/bbb.c . . . bbb.txtの中身 ファイルパス/ファイル名 x/y/z/aaa_x.c xx/yy/zz/bbb_x.c . . . 考えている処理は (1)aaa.txtからファイル名を抜き出す(basename ?) →結果を変数(AAA)に代入 (2)抜き出したファイル名に_xを追加(.を_x.に置き換え)した変数(BBB)でbbb.txtを検索 (3)変数AAAとBBBのdiffをとる>>txtファイルに出力する shellをうまくつかいこなせず、すみませんが教えていただければと思います。

  • N88互換BASICのプログラムについて。

    私は機械科3年ですが、今年からBASICを勉強しています。次のプログラムのエラー(行番号190にてopenしたファイルに出力できないです)がどうしても解決できないです。N88互換BASICやられている方でどなたか私にアドバイスをしていただけると助かります。 110 REM EX1B by E/F on 2006/04/25 120 PI=3.14159:PHI=30:Y0=.5 130 '************ Output into File ************ 140 CLOSE #1:OPEN "C:\WINBASIC\EX1B_OUT.TXT" FOR OUTPUT AS #1 150 FOR X=0 TO 360 STEP 45 160 A=.2 :Y1=A*SIN((X-PHI))+Y0 170 A=1.2 :Y2=A*SIN((X-PHI))+Y0 180 A=2 :Y3=A*SIN((X-PHI))+Y0 190 PRINT #1,X;",";Y1;",";Y2;",";Y3" 200 PRINT"Out:";X;",";Y1;",";Y2;",";Y3 210 NEXT X 220 CLOSE #1 230 '************ Input from File ************** 240 CLOSE #2:OPEN "C:\WINBASIC\EX1B_OUT.TXT" FOR INPUT AS #2 250 IF EOF(2)<>0 THEN GOTO 190 260 INPUT #2,X,Y1,Y2,Y3 270 PRINT"Inp:x=";X;" y1=";Y1;" y2=";Y2;" y3=";Y3;" 280 GOTO 150 290 CLOSE #2 300 '***** Close All Files and Computer Stop***** 310 CLOSE 320 END

  • getcharをしながらwhile文で出力すると一つ多く出力されるので

    getcharをしながらwhile文で出力すると一つ多く出力されるのです・・・。 変な現象に遭遇しました。1文字入力して「入力した文字は~です。」とxが入力されるまで繰り返してくださいというプログラムを書きました↓ #include <stdio.h> main() { char a; do { a = getchar(); printf("入力した文字は%cです。",a); } while(a != 'x'); } ところが実行して、たとえばキーボードのaを押してenterキーを押すと 入力した文字はaです。入力した文字は です。 と表示されるのです!!「入力した文字はaです。」だけでいいのに1つ多く出力されます。このソースは間違ってますか? すみません、教えてください(涙)

  • 固有値についての質問です(わかりづらい文かもしれません^^;)

    行列A{0 1 -1}    {1 0  1}    {-1 1 0} についてその固有値と固有空間の基底と次元を求める問題をやっていて固有値をといたところ-2と1(重複度2)と出て、-2のときの基底と次元は容易に出せたのですが1のときに-2と同じように (A-I)*X=0  X=(x y z) すなわち -x+y-z=0、x-y+z=0、-x+y-z=0をとこうとしたら解がいくつも考えられてしまって混乱してしまいました結局回答を見たところこの方程式を解くと X=b<1 1 0>+c<-1 0 1>となるらしいのですが、このXを求める方法がわかりません参考書をみても結果しか書いていないので困ってますどうかわかる方 教えていただけるとうれしいです

  • pascalにおけるwhile文の条件について

    「cがA,B,Cのどれかの場合はwhile文の内容を繰り返す」というプログラムは while c in ['A','B','C'] do begin ~ end; と書けますが、「cがA,B,Cのどれかで無い場合はwhile文の内容を繰り返す」というプログラムはどのように書けばよいのでしょうか。私は while not c in ['A','B','C'] do begin ~ end; だと思ったのですが、エラーが発生したのでどうやら違うようです。 わかる人がいれば教えてください。よろしくお願いします。

  • perlでASCII制御文字(キャレット記法)表示

    (10進数で)0から31までに相当する、キャレット記法のASCII制御文字(\0,^A,^B,^C,^D,^E,^F,^G,^H,^I,\n,^K,\f,\r,^N,^O,^P,^Q,^R,^S,^T,^U,^V,^W,^X,^Y,^Z,^[,^\,^],^^,^_)をシェルスクリプトを使わずにperlプログラムで導出するプログラムはどうやって書けば良いのでしょうか? (以下のように、エラーを利用した回りくどい方法で考えましたがもっと簡単な方法はありませんか?) open TEMP,">& STDERR"; open STDERR,"> ascii.txt"; for (0..31){ printf ("%c",chr($_)); } open STDERR,">& TEMP"; close TEMP; open IN,"< ascii.txt"; while (<IN>){ /"(.{2})"/; print "$1,"; } close IN;

    • ベストアンサー
    • Perl
  • Perlのプログラミングについて

    Perlのプログラミングでつまづきました。 # ファイルから指定文字列を含む行を収集する # 入力ファイルのオープンと読み込み print( "入力ファイル名?" ); $n = <STDIN>; chomp( $n ); open( FIN, "<$n" ) or die "入力ファイルオープンエラー: $!\n"; $n = @a = <FIN>; close( FIN ); print( "$n 行読み込みました\n" ); # 行の収集 print( "検索文字列?" ); $x = <STDIN>; chomp( $x ); $ptn = $x; #指定の文字列 $x = @b = grep( /$ptn/, @a ); print( "$x 行見つかりました\n" ); # 出力ファイルのオープンと書き出し print( "出力ファイル名?" ); $y = <STDIN>; chomp( $y ); open( FOUT, ">$y" ) or die "出力ファイルオープンエラー: $!\n"; print FOUT ( $ptn, "\n" ); print FOUT ( $x, "\n" ); print FOUT ( @b ); close( FOUT ); というプログラムで実行すると C:\My Perl\pl>perl プログラムの実行.pl 入力ファイル名?sample1.txt 168 行読み込みました 検索文字列?k 45 行見つかりました 出力ファイル名?out3-24.txt 続行するには何かキーを押してください . . . となり出力ファイルの中身が表示されません。 どこを間違えているのかご指摘いただけないでしょうか?